一、布局管理类基本知识
布局管理:使得界面中的部件有一个整齐的排序,还可以使得界面能适应窗口的大小变化。Qt主要提供了QLayout类及其子类作为布局管理器。Qt的布局管理系统提供了强大的机制自动排列窗口中的所有部件,确保它们有效的使用空间。
1、开发界面程序,一定会涉及到布局的问题。我们需要让控件显示在理想中的位置,可以直接设置控件的坐标和宽高。但是这样带来一个问题,当用户改变窗口大小时,例如点击最大化按钮或者拖拽窗口边缘,控件是不会改变的(包括控件的坐标和宽高)。因为在窗口改变时,你没有告诉程序是否更新控件以及如何更新。如果需要让控件自动更新,那么就要自己来写一些函数来相应这些变化。针对这种情况,Qt提供了一种机制 - 布局,来解决这个问题(大部分用于开发界面程序的语言或者框架,都会提供类似的机制)。只需要将控件放入某一种布局,当位置大小改变的时候,Qt使用布局管理器来调整。
2、Qt中提供了五种布局方式供我们选择:
- QHBoxLayout:按照水平方向从左到右布局
- QVBoxLayout:按照垂直方向从上到下布局
- QGridLayout:栅格布局,在一个网格中布局,类似于HTML中的table
- QFormLayout:按照表格布局,每一行前面是一个文本,文本后面跟随一个组件
- QStackedLayout:层叠的布局,允许将几个组件按照z轴布局,可以实现类似于ios中标签控制器的效果
3、Qt组件面板上用于布局的组件
二、简单应用举例
方法一:使用布局管理器布局:
(1)拖入三个按钮Push Button和一个Vertical Layout(垂直布局管理器)到界面上
(2)然后将三个按钮拖入到布局管理器中,这时三个按钮就会自动垂直排列,并且进行水平拉伸,无论如何改变布局管理器的大小,按钮总是水平方向变化。
方法二:使用分裂器(QSplitter)来进行布局
(1)选择三个按钮,点击使用分裂器垂直布局
补充:在设计窗体的上方有一个工具栏,用于调整设计器进入不同的状态,以及进行布局设计,工具栏上各按钮的功能如下所示
三、综合实例
设计要求:
- 单击 UnderLine、Italic、Bold 3 个 CheckBox 时,根据其状态,设置 PlainTextEdit 里的文字的字体样式;
- Black、Red、Blue 3 个 RadioButton 是互斥选择的,单击某个 RadioButton 时,设置文字的颜色;
- 单击“确定”“取消”或“退出”按钮时,关闭窗口,退出程序。
(1)界面设计
(2)实现文本框中的字化底线的功能
1)添加信号和槽
2)编写槽函数的内容
//槽函数,为文本框中的字添加下划线
void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
QFont font =ui->txtEdit->font();
font.setUnderline(checked);
ui->txtEdit->setFont(font);
}
(3)实现3 个 RadioButton 互斥选择,设置文字颜色
设置字体的 3 个 RadioButton 是互斥性选择的,即一次只有一个 RadioButton 被选中,虽然也可以采用可视化设计的方式设计其 clicked() 信号的槽函数,但是这样就需要生成 3 个槽函数。这里可以简化设计,即设计一个槽函数,将 3 个 RadioButton 的 clicked() 信号关联到这一个槽函数。
1)在 QWDialog 类的 private slots 部分增加一个槽函数定义如下
定义槽函数:
提示 将鼠标光标移动到这个函数的函数名上面,单击右键,在弹出的快捷菜单中选择“Refactor”→“Add Definition in qwdialog.cpp”,就可以在 qwdialog.cpp 文件中自动为函数 setTextFontColor() 生成一个函数框架。
生成槽函数:
2)在 qwdialog.cpp 文件中,为 setTextFontColor() 编写实现代码如下
编写槽函数的内容:
//设置字体颜色
void QWDialog::setTextFontColor()
{
QPalette plet=ui->txtEdit->palette();
if (ui->rBtnBlue->isChecked())
plet.setColor(QPalette::Text,Qt::blue);
else if (ui->rBtnRed->isChecked())
plet.setColor(QPalette::Text,Qt::red);
else if (ui->rBtnBlack->isChecked())
plet.setColor(QPalette::Text,Qt::black);
else
plet.setColor(QPalette::Text,Qt::black);
ui->txtEdit->setPalette(plet);
}
3)槽函数是自定义的,所以不会自动与 RadioButton 的 clicked() 事件关联,此时编译后运行程序不会实现改变字体颜色的功能。需要在 QWDialog 的构造函数中手工进行关联
手工进行关联:
QWDialog::QWDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::QWDialog)
{
ui->setupUi(this);
connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
}
(4)三个按钮功能设计
界面上还有“确定”“取消”“退出”3 个按钮,这是在对话框中常见的按钮。“确定”表示确认选择并关闭对话框,“取消”表示取消选择并关闭对话框,“退出”则直接关闭对话框。
QWDialog 是从 QDialog 继承而来的,QDialog 提供了 accept()、reject()、close() 等槽函数来表示这三种状态,只需将按钮的 clicked() 信号与相应槽函数关联即可。
1)在 UI 设计器里,单击上方工具栏里的“Edit Signals/Slots”按钮,窗体进入信号与槽函数编辑状态
2)将鼠标移动到“确定”按钮上方,再按下鼠标左键,移动到窗体的空白区域释放左键,这时出现如图 11 所示的关联设置对话框。
同样的方法可以将 btnCancel 的 clicked() 信号与 QWDialog 的 reject() 槽函数关联,将 btnClose 的 clicked() 信号与 QWDialog 的 close() 槽函数关联。
三、事件系统
事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的通常。在Qt中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等。
QT中使用一个对象来表示一个事件,继承自QEvent类,事件与信号不同,任何QObject子类实例都可以接收和处理事件。
1、QT中事件和信号
(1)信号:信号不是事件,信号的本质是回调函数,在一个线程中可看做是同步操作,同时信号的发出者是对象,信号不会循环,接收者会立即收到;
(2)事件:事件一般是通过postEvent()函数进入到进程主循环事件队列中,是异步操作 ;事件的发出者一般是窗口系统,少数来自系统的内部;
(3)不同点:
- 信号有具体的对象发出,然后马上交给connect()函数连接的槽进行处理,而对于事件,Qt使用一个队列事件对所有的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部。
- 信号一旦发出,槽函数一定会执行,事件可以用过滤器过滤.
- 信号与槽中,发送者所在的线程是无关紧要的。在自动连接情况下,Qt需要查看信号发出的线程是不是和信号接收者的线程一致,来决定连接的类型。