定义信号,如:
signals:
void launch(QString &str); //声明一个信号, 信号不能具体实现
发射信号,如:
private slots:
void reception() { //响应信号的槽函数
QString str = "响应了 launch() 信号!";
emit launch(str); //发射信号
}
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以声明在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
声明三个槽方法,如:
private slots:
void reception(); //响应信号的槽函数
void reception2();
void accept(QString &str);
槽方法中处理需要处理的工作,如:
void MainWindow::accept(QString &str){ //MainWindow.cpp中实现槽方法
qDebug() << str; //调试输出 添加头文件 #include
}
GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
信号与槽关联是用 QObject::connect() 函数实现:
QMetaObject::Connection QObject::connect(
const QObject *sender, //信号发送者
const char *signal, //发送的信号
const QObject *receiver, //信号接收者
const char *method, //表示与信号连接的方式的字符串,可以是槽或信号
Qt::ConnectionType type = Qt::AutoConnection //连接方式,默认自动连接
)
常用格式:connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
用来表示信号和槽的参数都是字符串,Qt提供了两个宏用于构造这样的字符串:对于信号使用SIGNAL,对于槽则使用SLOT,用它们将函数的原型包围起来即可。注意connect方法采用SIGNAL()及SLOT()时,这里的函数原型只能写出类型,不能有任何参数名,否则连接将会失败。
同时信号与槽连接方式:
序号 | 代码 | 连接方式 |
---|---|---|
1) | Qt::AutoConnection: | (默认连接方式)自动方式,由系统自动选择连接方式。 |
2) | Qt::DirectConnection: | 直接方式,信号发射时,立即调用槽。 |
3) | Qt::AutoConnection: | 队列方式,信号发射时产生一个事件进入队列,事件被处理时槽才能调用。 |
4) | Qt::BlockQueuedConnection: | 阻塞队列方式,信号发射时产生一个事件进入队列,然后当前线程进入阻塞状态,直到事件处理完毕,若接收方位于发送信号的线程中,则程序会死锁,故此连接方式仅用于多线程。 |
信号可以看做是特殊的函数,需要带括号,可带参数,信号无需实现也不能实现。槽函数需要带括号,有参数时还需要指明参数。当信号和槽函数带有参数时,在 connect()函数里,要写明参数的类型。信号的参数需与槽的参数列表一致,允许比槽参数多。如果不匹配或参数过少,会出现编译错误或运行错误。在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT。当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
signals: void launch(QString &str); //声明信号
private slots: void accept(QString &str); //声明槽函数
//connect连接信号与槽
connect(this, SIGNAL(launch(QString&)), this, SLOT(accept(QString&)));
signals: void launch(QString &str); //声明信号
signals: void launch2(); //声明信号
//connect连接信号与信号
connect(this, SIGNAL(launch(QString&)), this, SIGNAL(launch2()));
signals: void launch(QString &str); //声明信号
private slots: void reception(); //响应信号的槽函数
private slots: void reception2(); //响应信号的槽函数
private slots: void reception3(); //响应信号的槽函数
//connect连接信号与槽
connect(this, SIGNAL(launch(QString&)), this, SLOT(reception()));
connect(this, SIGNAL(launch(QString&)), this, SLOT(reception2()));
connect(this, SIGNAL(launch(QString&)), this, SLOT(reception3()));
signals: void launch(QString &str); //声明信号
signals: void launch2(); //声明信号
signals: void launch3(); //声明信号
private slots: void reception(); //响应信号的槽函数
//connect连接信号与槽
connect(this, SIGNAL(launch(QString&)), this, SLOT(reception()));
connect(this, SIGNAL(launch2()), this, SLOT(reception()));
connect(this, SIGNAL(launch3()), this, SLOT(reception()));
//元对象声明
QObject::disconnect(const QObject* sender,const char* signal, const QObject *receiver,const char* method);
1. 断开与一个对象所有的信号的所有关联
//断开sender对象与所有的信号连接
disconnect(sender,0,0,0);
相当于:
sender->disconnect();
2. 断开与一个指定信号的所有关联
//断开了 single1() 信号 与所有响应的槽函数连接
disconnect(sender, SIGNAL(single1()), 0, 0);
相当于:
sender->disconnect(SIGNAL(single1()));
3. 断开与一个指定接受者receiver的所有关联
disconnect(sender, 0, receiver, 0);
相当于:
sender->disconnect(SIGNAL(single1()));
4. 断开指定信号与槽的关联:
//断开了 single1() 信号, 与 slotFun() 槽函数的连接
disconnect(sender, SIGNAL(single1()), receiver, SLOT(slotFun()));
或者:
//使用connect的返回值
QMetaObject::Connection ret = connect(sender, SIGNAL(single1()), receiver, SLOT(slotFun()));
disconnect(ret); //ret为connect()的返回值
如: