需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。
目录
一、Qt中的信号和槽
1、信号
信号源:由哪个控件产生的信号
信号的类型:用户对GUI界面的不同操作,就可能触发不同的信号(点击、移动光标、勾选、下拉等)
2、槽
信号的处理方式:槽 =>处理信号的回调函数
Qt使用connect这样的函数,把一个信号和一个槽关联起来。信号触发,自动回调信号处理函数。
3、Q_OBJECT
如果一个类要使用信号和槽,必须在类中添加Q_OBJECT这个宏
二、Qt中的connect函数
connect是QObject(Qt中其他类的"祖先类")提供的静态成员函数。
cpp
bool QObject::connect(const QObject *sender,
const QMetaMethod &signal,
const QObject *receiver,
const QMetaMethod &method, Qt::ConnectionType type=Qt::AutoConnection);
- const QObject *sender: 哪个控件?
- const QMetaMethod &signal: 哪种信号?(必须是信号源自带或继承自父类的信号)
- const QObject *receiver: 哪个对象负责处理?
- const QMetaMethod &method: 用于处理信号的槽函数。(要处理信号的对象提供的成员函数)
- Qt::ConnectionType type: 连接类型,它可以指定连接的类型,如自动连接、直接连接等。通常不需要手动设定。
- 第一个和第二个参数,第三个和第四个参数类型要对上才行。
[signal] void QAbstractButton::clicked (bool checked = false)
This signal is emitted when the button is activated (i.e., pressed down then released while the mouse cursor is inside the button), when the shortcut key is typed, or when click() or animateClick() is called. Notably, this signal is not emitted if you call setDown(), setChecked() or toggle().
If the button is checkable, checked is true if the button is checked, or false if the button is unchecked.
See also pressed(), released(), and toggled().
三、自定义信号、自定义槽
1、自定义槽函数
槽函数一般用于用户触发某个操作后,需要执行的业务逻辑。所以需要自定义槽函数。
1.1使用代码创建控件的方式
1.2使用ui创建控件的方式
自动生成的槽函数的名字是on_pushButton_clicked,其中on是固定的,pushButton是ui中的objectName,clicked写明了是哪种信号。所以ui自动生成的槽函数不需要connect函数就能在触发信号时被回调。(ui_widget.h中调用了QMetaObject::connectSlotsByName,它会触发自动连接信号槽的规则)
2、自定义信号
自定义信号很少用到。因为在GUI中,用户的操作行为是可以穷举的,Qt内置的信号已经覆盖到了大部分可能的用户操作。
如果真的需要自定义信号:
1、信号是一种特殊的函数,程序员只需写出函数声明,并告诉Qt,这是一个信号即可。这个函数的定义,是Qt在编译过程中,自动生成的。(无法干预)
2、信号函数的返回值必须是void,有没有参数都可以,也支持函数重载。
3、信号可以使用emit关键字进行发射。(Qt5 emit不写也行)
四、带参数的信号和槽
信号和槽也可以带参数。发射信号时,就可以给信号函数传递实参,这个参数就会被传递到对应的槽函数中。
信号和槽函数的参数类型必须一致,个数可以不一致,但是信号的参数个数必须大于槽函数的参数个数。
一个信号通过connect关联多个槽函数,一个槽函数也能被多个信号关联。
五、信号和槽断开连接
使用disconnect断开信号槽的连接(主动断开往往是把信号重新绑定到另一个槽函数上)
如果这里的代码没有disconnect,会使一个信号绑定两个槽函数,触发点击按钮,同时执行两个槽函数。
六、使用lambda表达式定义槽函数
注意被捕获变量的生命周期。
尽量传值捕获,传引用捕获可能会捕获到已经被释放的变量,造成段错误。例如:
上图传值捕获没问题,传引用捕获会崩溃。原因是button是局部变量(它指向的空间位于堆区,但它自己是一个局部变量的指针),构造函数结束后button变量即被销毁,造成段错误。