创建UI界面
Qt是一个十分庞大的框架,Qt Widgets中有着非常丰富的控件,我们可以直接用C++代码生成GUI界面,也可以使用Qt Creator的设计器生成界面。这里我们简单介绍一下如何在Qt中使用各种控件,以及如何使用布局和修改样式。
使用C++代码组织布局和控件
下面的例子代码中,使用纯C++代码编写了一个登陆框。
main.cpp
#include <QApplication>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
//主窗口
QWidget w;
//创建一个GridLayout布局
QGridLayout gridLayout(&w);
//在第0和3列设置弹簧,参数是列坐标和权重
gridLayout.setColumnStretch(0, 1);
gridLayout.setColumnStretch(3, 1);
//初始化四个控件:用户名标签,用户名输入框,密码标签,密码输入框
//并添加到布局中,参数是行列坐标
QLabel usernameLabel("用户名");
gridLayout.addWidget(&usernameLabel, 0, 1);
QLineEdit usernameLineEdit;
gridLayout.addWidget(&usernameLineEdit, 0, 2);
QLabel passwordLabel("密码");
gridLayout.addWidget(&passwordLabel, 1, 1);
QLineEdit passwordLineEdit;
passwordLineEdit.setEchoMode(QLineEdit::Password);
gridLayout.addWidget(&passwordLineEdit, 1, 2);
//创建一个HBoxLayout作为子布局
QHBoxLayout hBoxLayout;
//向HBoxLayout添加两个按钮
QPushButton resetButton("重置");
hBoxLayout.addWidget(&resetButton);
QPushButton submitButton("登录");
hBoxLayout.addWidget(&submitButton);
//将HBoxLayout添加到GridLayout中
gridLayout.addLayout(&hBoxLayout, 2, 2);
//为主窗口widget设置布局
w.setLayout(&gridLayout);
//显示主窗口
w.show();
return app.exec();
}
上面代码已经简单介绍了几种常用的控件:QLabel、QLineEdit、QPushButton。从代码中我们可以发现,每个Widget控件都包含在一个头文件中,比如我们现在想要试用按钮控件(QPushButton),那么我们首先要做的就是引入头文件#include <QPushButton>,实例化一个按钮对象后,把它安排到合适的位置,调用合适的API实现正确的功能,我们的程序就是这样一步步构建起来的。
布局(Layout)的使用和控件差不多,同样需要先引入头文件,每个布局都有不同的用法, 但是实际上常用的布局就那么几个,用到时查文档即可。
运行结果:

使用Qt设计器组织布局和控件
这里我们创建一个Qt Widgets工程,实际上工程为我们自动创建了一个QMainWindow的主窗口,为了和上面例子保持一致,这里我们再创建一个基于QWidget的窗口布局文件,Qt Creator中选择File->New File->Qt Designer Form Class,然后添加基于QWidget的窗口。以上操作会创建一个.ui文件,以及一组.cpp和.h文件组成的C++类。
myform.h
#ifndef MYFORM_H
#define MYFORM_H
#include <QWidget>
namespace Ui {
class MyForm;
}
class MyForm : public QWidget
{
Q_OBJECT
public:
explicit MyForm(QWidget *parent = nullptr);
~MyForm();
private:
Ui::MyForm *ui;
};
#endif // MYFORM_H
myform.cpp
#include "myform.h"
#include "ui_myform.h"
MyForm::MyForm(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyForm)
{
ui->setupUi(this);
}
MyForm::~MyForm()
{
delete ui;
}
至于.ui文件实际上是一个XML文件,它描述了窗口的控件和布局,在编译阶段会生成界面布局的C++代码。双击.ui文件即可打开设计器,设计器使用很简单,和Visual Studio基本差不多,从右边往编辑区拖控件就行了。

这里我们拖个和之前一样的登录框,使用设计器比用C++代码堆界面更简单更容易维护。注意,根组件的布局不是拖进去的,而是拖入几个控件后,在根组件上右击,选择布局子菜单进行设置的。

使用以下代码在程序中加载并显示这个新创建的窗口。
main.cpp
#include <QApplication>
#include "myform.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyForm myForm;
myForm.show();
return app.exec();
}
有关窗口类的详细使用将在后续章节详细介绍。
使用QSS修改控件样式
Qt的一个强大之处是支持QSS样式表(类似Web开发中的CSS),我们通过QSS可以轻松修改控件的样式表现,这里我们编写一个简单的例子来介绍QSS的用法,具体QSS支持哪些样式表属性可以参考官方文档。
为控件添加样式表需要修改QWidget的styleSheet属性,我们可以在C++代码中设置QSS字符串,也可以直接在设计器中修改控件的该属性。

在设计器中,我们点击编辑styleSheet属性的按钮,即可弹出修改QSS的窗口,这里我们可以参照文档设置QSS。我这里对一个按钮设置了它的圆角边框、背景颜色和文字颜色,QSS写法和CSS基本一致。

使用QSS的另一种方法是我们编写一个单独的QSS文件然后将其添加到资源文件中,在程序启动时加载其中的内容。不过这种方式有一个缺点,我们没法在设计器中预览附加QSS后的样式。
app.qss
QPushButton#pushButton {
border-radius: 5px;
background-color: rgb(0, 0, 0);
color: rgb(255, 255, 255);
}
main.cpp
#include <QApplication>
#include <QFile>
#include <QHostInfo>
#include <QIODevice>
#include <QSqlDatabase>
#include "mywindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWindow mw;
QFile file(":/qss/qss");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString qss = file.readAll();
mw.setStyleSheet(qss);
file.close();
}
mw.show();
return app.exec();
}
在app.qss中我们使用了QPushButton#pushButton {}这样的写法,这是一种选择器语法,QPushButton是控件的类型,#pushButton是控件的变量名。在C++代码中,我们将QSS内容读出,并附加到了MyWindow窗口上,该窗口中对应的按钮将被赋予对应的QSS样式。