Base Qt 5.9
新建控制台app
.pro文件内容
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp
main.cpp:
// Qt头文件没有.h, 头文件和类名相同
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}
这个build下,就可以看见一个cmd窗口了。
新建Widget app
在构建的第三步时选择 Base class,选择QWidget class。
在选择窗口会有 .pro
文件和Headers Sources Froms(ui文件)文件夹。
看下 .pro
文件:
QT += core gui
# 如果需要sql,则如下
# QT += sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test2
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
剩下的就是看如何操控控件了。我们先放一个 Label和 Push Button到窗体上。
- 打开UI文件, 在
Display Widgets
窗体中拖拽Label 图标放到窗体上,然后在属性编辑器上修改其属性,属性编辑器上面是对象(Object)窗体,可以看出来继承关系。
objectName表示组件的对象名称,界面上的每个组件都需要一个唯一的对象名称,以便引用。
Push Button的类名字QPushButton,objectName是btnClose
.
在界面设计时,对程序需要访问的组件修改其objectName,对于其他的则可不必了。
- 添加信号槽 想要达到单击close按钮,窗口就退出的效果,就需要添加Signals和Slots了。
在信号与槽的窗体中(就是窗口下方,带加号、减号的那个窗体), 单击Add
按钮,会出现 sender, Signal, Receiver, Slot
一行输入栏。
单击Sender
选择 btnClose,Signal 选择clicked()
, Receiver选择窗体Widget, Slot选择close()
.
然后编译就可以出现app,点击close就可以关闭窗口了。
创建QDialog app
new -> project -> 第三步选择 base class QDialog,上面的类名为什么名字,就会生成什么名字的cpp,如QWDialog,则会生成qwdialog.cpp文件等(还有UI文件)。
这个demo的目的是创建一个可以修改字体的窗口。
-
首先在 input widgets中拖拽Plain Text Editor(类名<-QWDialog),对象名修改为txtEdit,编辑敲入文字: IT is my demo.
-
在Buttons窗口中取到Check Box, ObjectName为chkBoxUnder,类似拖拽三个check box。文字描述分别为 “Italic”和“BOLD”,同时修改objectName.
-
设置字体颜色: 在 Buttons窗口中取到 Radio Button,然后red black blue文字,并修改各自的objectName.
-
设置三个push button,确定 取消 退出。
objectName设置好了轻易不要改动。
-
A 为了将这些组件排列美观,最好使用组件布局,也就是说需要使用一些容器。如 QGroupBox,使用其把上面的分成2组。这是层次关系。
-
B 布局管理: 在UI设计中,组件面板有Layouts和Spacers两个组件面板。 比如,可以把三个PushButton的按钮放在Horizontal Layout下面,其会用红色框起来。这样 PushButton就可以完全以水平组合起来,放置在同一位置上。
C: 快速布局: 在2, 3步时使用 Group Box将三个按钮组合起来了,我们可以只点击Grouo Box,然后单击窗口上方的 水平 按钮,三个 组件 就会水平分布,并且改变外部的大小,也会改变组件的大小。
D: 然后选择最外层的窗体,单击 垂直 分布,就可以达到自动平铺的效果了。
伙伴关系和Tab顺序
伙伴关系设置快捷键的, Tab顺序控制tab的执行顺序。
信号与槽
信号 Signal就是在特定条件下被发射的事件。 如 PushButton最常见的信号就是鼠标单击发射的clicked()信号。 GUI编程的核心就是对界面上各组件的信号响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就行了。
Slot 槽就是对信号响应的函数。槽就是一个函数,和C++类似,可以定义在类的任何部分(public private protected等),可以具有任何参数,也可以被直接调用。唯一的区别就是: 槽函数可以与一个信号进行关联,当信号发射时,关联的槽函数被自动执行。
信号与槽关联使用 QObject::connect()函数进行关联的,其基本格式:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()))
connect()是QObject类的一个静态函数, 而QObject是所有的Qt类的基类,在实际调用时可以忽略前面的QObject限定。
sender是发射信号的对象名称, signal是信号名称, receiver是接受信号的对象名称,slot()是槽函数的名称。
目标:
过程:
单击chkBoxUnder, 右键 go to slot, 第一步是选择信号,在那个方框下,有对象chkBoxUnder的所有信号。我们选择 clicked(bool), 这样会传递一个参数, 在响应代码里是可以直接利用这个参数。也会在qwdialog.h中添加一个private slots的槽函数声明:
class QWDialog : public QDialog
{
Q_OBJECT
public:
explicit QWDialog(QWidget *parent = 0);
~QWDialog();
// 自动添加部分
private slots:
void on_chkBoxUnder_clicked(bool checked);
private:
Ui::QWDialog *ui;
};
这时,代码就会跳转到qwdialog.cpp:生成以下代码:
void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
}
我们完善这个处理函数。
void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
QFont font = ui->txtEdit->font();
font.setUnderline(checked);
ui->txtEdit->setFont(font); // 需要回置
}
- 同样的方式设置 Italic和Bold两个CheckBox两个方式。build后运行,发现我们可以设置字体的特性了, 说明信号与槽函数已经关联了。
这里我们自己的代码没有看到connect在哪里,是有问题吗? 不是的,可以查看编译生成的ui_qwdialog.h文件(在工程文件下,可以find usage去找一下,编辑器里是发现不了的)
在setupUi
里面,有一个函数是这样的:QMetaObject::connectSlotsByName(QWDialog);
, 这条语句将搜索QWDialog界面上的所有组件,将信号与槽函数匹配起来,它假设的槽函数名称是:
void on_<objectName>_<signal name>(<signal parameters>)
- 字体颜色设计
将3个RadioButton的clicked()信号关联到一个槽函数, 在 QWDialog类的private slots部分增加一个槽函数:
void setTextFontColor();
然后在qwdialog.cpp中实现具体函数(方法是在.h的slot部分, 右击->refactor->add definition in xx.cpp)就可以了。
具体显示如下:
void QWDialog::setTextFontColor()
{
QPalette plet = ui->txtEdit->palette(); // unknown usgae
if (ui->rBtnBlue->isChecked())
plet.setColor(QPalette::Text, Qt::blue);
else if (ui->rBtnBlack->isChecked())
plet.setColor(QPalette::Text, Qt::black);
else if (ui->rBtnRed->isChecked())
plet.setColor(QPalette::Text, Qt::red);
else
plet.setColor(QPalette::Text, Qt::black);
ui->txtEdit->setPalette(plet);
}
由于是自定义的槽函数,并不会自动与RadioButton进行关联,需要在QWDialog的构造函数中进行手工关联,代码如下:
QWDialog::QWDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::QWDialog)
{
ui->setupUi(this);
// 以下内容为删除部分 :
connect(ui->rBtnBlack, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
connect(ui->rBtnBlue, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
connect(ui->rBtnRed, SIGNAL(clicked()), this, SLOT(setTextFontColor()));
}
此时编译后就可以改变字体颜色了。
- 三个按钮的功能设计
还有 确定 取消 退出三个按钮。字如其意,最后的结果都是退出窗体。
过程: QWDialog是从QDialog继承过来的, QDialog提供了accept() reject() close()等槽函数来表示这三种状态,所以只需要将clicked()信号与相应的槽函数进行关联即可。
demo finish。