1 UI控件的信号槽(以QPushButton为例)
QT的各种UI控件(例如按钮,滑动条,标签等),都有很多信号,这些信号在控件状态变化时(比如鼠标按下的时候)信号会自动触发。
在“按钮”控件上鼠标右击可以转到槽,可以看到,QPushButton类总共有12个不同的信号,分别继承自QAbstractButton, QObject, Qwidget。
最常用的就是:
clicked() —— 鼠标左键松开时触发一次
pressed() —— 鼠标左键按下时触发一次
点击ok可以转到该按钮的clicked槽函数,在该按钮的clicked信号触发时(即鼠标点击该按钮并松开的瞬间),程序会跳转到该槽函数,执行其中的代码。
// ui->pushButton 的槽函数
void MainWindow::on_pushButton_clicked()
{
//... Code executed when the button is clicked
}
总结:
新建:UI控件的信号无须创建;槽使用 “右键转到槽” 的方法即可新建。
连接:将槽函数命名为:on_控件名_信号名 ,信号会自动连接到槽,无须手动进行连接。
触发:当控件状态改变时信号就会自动触发,因为已经进行了信号槽连接,所以槽的代码就会自动执行。
2 自定义的信号槽(以两个类之间传递信号为例)
注意:如果想在两个类之间使用信号槽传递信号,必要条件是这两个类都直接或间接继承自QObject类,并且在类中声明宏 Q_OBJECT。
实现效果:
点击按钮后,MyClass类会发送一个带参信号给Mainwindow类,这个参数类型是QString,Mainwindow类收到信号后将参数内容打印出来。
代码如下:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void myslot(QString); //定义私有槽
private:
Ui::MainWindow *ui;
};
//公有继承自 QObject
class MyClass : public QObject
{
Q_OBJECT //声明宏,为了可以使用信号槽机制
public:
MyClass(){}
~MyClass(){}
signals:
void mysignal(QString); //定义信号(信号全部是公有的)
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MyClass myclass; //MyClass实例化
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//信号槽连接
this->connect(&myclass,SIGNAL(mysignal(QString)), \
this,SLOT(myslot(QString)),Qt::AutoConnection);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
//触发信号(推荐在本类触发信号,这里只是为了演示目的)
emit myclass.mysignal("这是一条来自myclass对象的信号");
}
//槽的实现
void MainWindow::myslot(QString str)
{
qDebug()<<str;
}
3 三点说明
关于信号槽连接方式
单线程中,只需要 Qt::AutoConnection (默认连接),形如:
connect(&myclass,SIGNAL(mysignal(QString)), \
this,SLOT(myslot(QString)));
connect(&myclass,SIGNAL(mysignal(QString)), \
this,SLOT(myslot(QString)),Qt::AutoConnection);
关于一对多和多对一
一个信号连接多个槽时,槽函数的执行顺序:按连接的先后顺序执行
多个信号连接多个槽时,可在槽函数中判断信号的发出者
关于利用信号槽传递自定义类型(例如MyType)
为了能够在队列中存储自定义类型参数,Qt需要去construct、destruct、copy这些对象,而为了让Qt知道怎样去作这些事情,参数的类型需要使用qRegisterMetaType来注册,否则编译器会报错。
qRegisterMetaType <MyType> ("MyType"); //注册参数类型MyType
QObject::connect(pObject,SIGNAL(mysignal(MyType)),this,SLOT(mylot(MyType)));