一、信号与槽详解
QT是一个跨平台的C++ GUI应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展等特点。信号与槽是QT自行定义的一种对象通信机制,是QT的核心机制。
信号与槽实际上是回调函数的一种体现。
1、信号
当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。当一个信号被发射时,与其相关联的槽将被立刻执行,就象一个正常的函数调用一样。只有当所有的槽返回以后发射函数(emit)才返回。 如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,但是它们执行的顺序将会是随机的、不确定的,我们不能人为地指定哪个先执行、哪个后执行。
signals:
void mySignal();
2、槽
槽是普通的C++成员函数,可以被正常调用,它们唯一的特殊性就是很多信号可以与其相关联。当与其关联的信号被发射时,这个槽就会被调用。
public slots:
void mySlot();
3、信号与槽的连接
只有将信号与槽关联在一起,当某个对象发送信号时,信号对应的槽才会被触发执行。通过调用QObject对象的connect函数来将某个对象的信号与另外一个对象的槽函数相关联,这样当发射者发射信号时,接收者的槽函数将被调用。该函数的申明如下:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
【Note】:
只有继承自QObject的对象才能使用信号与槽。
4、信号与槽之间的关系
- 一个信号可以连接多个槽:当信号发射时,会以不确定的顺序一个接一个的调用各个槽。
- 多个信号可以连接同一个槽: 即无论是哪一个信号被发射,都会调用这个槽。
- 信号直接可以相互连接:发射第一个信号时,也会发射第二个信号。
- 信号的参数与槽的参数的关系:信号的参数个数必须大于等于槽的参数个数,并且与槽的参数类型要一一对应,超过槽的参数后面的参数会被忽略。需要注意的是,槽的参数不能有缺省值。
二、Qt基本控件及三大布局
【基本控件】:
- QLabel:用于显示文本和图像,但是没有用户交互可用。
- QComboBox:以占用最少屏幕空间的方式向用户显示选项列表。
- QLineEdit:是允许输入和编辑单行纯文本的控件。
- QCheckBox:复选框,是一个具有两种状态:打开和关闭的控制。
- QProgressBar:用于向用户提供操作进度条。
- QPixmap:是用于处理图像的控制之一。
- QTableWidget:是电子表格应用程序中使用的独特控件(它也称为网格控件),是一个更复杂的控件。
【三大布局】:
- QHBoxLayout: 水平显示布局,所有在其上面摆放的控件只能水平排列下去;
- QVBoxLayout: 垂直显示布局,所有在其上面摆放的控件只能垂直排列下去;
- QGridLayout :格子显示布局,可以按照表格的形式显示布局;
三、QT中的模态对话框与非模态对话框
模态对话框(Modal Dialog)与非模态对话框(Modeless Dialog)的概念不是Qt所独有的,在各种不同的平台下都存在。又有叫法是称为模式对话框,无模式对话框等。所谓模态对话框就是在其没有被关闭之前,用户不能与同一个应用程序的其他窗口进行交互,直到该对话框关闭。对于非模态对话框,当被打开时,用户既可选择和该对话框进行交互,也可以选择同应用程序的其他窗口交互。
四、dialog、widget、mainwindow的区别
- dialog有exec函数,如果是dialog窗口,后边的窗口时不可选的;
- widget和dialog都有show函数,如果通过这个函数显示这两种类型的窗口,则两个窗口都是可选的; widget主要是在上面放置布局和控件;
- mainwindow可以显示菜单,工具栏,状态栏、托盘等功能。
五、QT中的事件处理
在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent。事件处理的核心包括事件产生、分发、接受和处理。
1、事件的产生
谁来产生事件? 最容易想到的是我们的输入设备,比如键盘、鼠标产生的keyPressEvent,keyReleaseEvent,mousePressEvent,mouseReleaseEvent事件(他们被封装成QMouseEvent和QKeyEvent)。
2、Qt中事件的分发
谁来负责分发事件?对于non-GUI的Qt程序,是由QCoreApplication负责将QEvent分发给QObject的子类-Receiver。对于Qt GUI程序,由QApplication来负责
3、事件的接受和处理
谁来接受和处理事件?答案是QObject。类是整个Qt对象模型的心脏,事件处理机制是QObject三大职责(内存管理、内省(intropection)与事件处理制)之一。任何一个想要接受并处理事件的对象均须继承自QObject,可以选择重载QObject::event()函数或事件的处理权转给父类。
4、事件(QEvent)和信号(SIGNAL)的不同
例如:单击界面上的按钮,那么就会产生鼠标事件QMouseEvent(不是按钮产生的),由于按钮被按下了,所以他会发出一个单击信号clicked()信号(是按钮产生的),这里只考虑单击信号而不用考虑鼠标事件,但如果要设计一个按钮,或者当单击按钮时让它产生别的效果,此时就要考虑鼠标事件了,由此,信号和事件是两个不同层面的东西,发出者不同,作用不同。Qt中,所有的QObject的子类实例均可对事件接收和处理! 另外:事件处理函数的返回值是有意义的,我们要根据这个返回值来确定是否还要继续事件的处理
。