Qt信号槽问题汇总
1. 發(fā)送一次信號,調(diào)用多次槽函數(shù)問題
在同一個(gè)類中,多次鏈接QObject::connect(sender, SIGNAL(signalSender(QString, int)), receiver, SLOT(onSignalSender(QString, int))); 會(huì)導(dǎo)致發(fā)送一次信號signalSender(QString, int) 多次調(diào)用槽函數(shù)(onSignalSender(QString, int),如果鏈接了一次,那么,發(fā)送一次signalSender信號,就調(diào)用一次onSignalSender槽函數(shù),如果鏈接了兩次,那么發(fā)送一次signalSender信號,就調(diào)用兩次onSignalSender槽函數(shù),。。。以此類推。
2. 信號的直接調(diào)用問題
在Qt中,一般發(fā)送信號都是通過 emit signalSender() 方式發(fā)送的,其實(shí)也可以通過直接調(diào)用信號 ?signalSender()進(jìn)行發(fā)送,此時(shí),如果調(diào)用了信號signalSender,且該信號通過connect進(jìn)行了鏈接,則會(huì)進(jìn)入對用鏈接的槽函數(shù)中執(zhí)行。 注意:在多線程中,直接調(diào)用是在調(diào)用者線程中執(zhí)行,發(fā)信號是在接收者線程中執(zhí)行
3.
信號是可以連接另一個(gè)信號的 例如 connect(push_button, &qpushlbutton::clicked, this, & qwidget :: buttonclicked );Qt信號與信號連接、Qt4連接寫法
1.信號與信號連接
更改代碼
#include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QPushButton>//Teacher類 //Student類 //下課后老師會(huì)觸發(fā)一個(gè)信號(餓了),學(xué)生響應(yīng)信號(請客吃飯)Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);//創(chuàng)建一個(gè)老師的對象this->th = new Teacher();//創(chuàng)建一個(gè)學(xué)生的對象this->stu = new Student();//重載連接,需要用到函數(shù)指針,指向明確的函數(shù)地址//無參函數(shù)連接,兩種寫法void(Teacher::* teacherSignal0)() = &Teacher::hungry;void(Student::* studentSlot0)(void) = &Student::treat;connect(th,teacherSignal0,stu,studentSlot0);//有參連接void(Teacher::* teacherSignal)(QString) = &Teacher::hungry;void(Student::* studentSlot)(QString) = &Student::treat;connect(th,teacherSignal,stu,studentSlot);//點(diǎn)擊叮叮叮按鈕,再觸發(fā)下課QPushButton* btn = new QPushButton("叮叮叮",this);//第一種實(shí)現(xiàn)//connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);//第二種實(shí)現(xiàn)//信號連接信號connect(btn,&QPushButton::clicked,th,teacherSignal0);resize(400,400); }void Widget::classIsOver() {//下課函數(shù),觸發(fā)后發(fā)送老師餓了的信號//emit出發(fā)信號 qt獨(dú)有語法emit th->hungry();emit th->hungry("昏睡紅茶");qDebug() << "------------"; }Widget::~Widget() {delete ui; }注意:信號連接時(shí),信號與槽的參數(shù)必須一一對應(yīng)。不然會(huì)報(bào)
static assertion failed: Signal and slot arguments are not compatible.
的bug。
擴(kuò)展內(nèi)容
Qt4版本以前的信號與槽的連接
連接無參
connect(th,SIGNAL(hungry()),stu,SLOT(treat()));
優(yōu)點(diǎn),參數(shù)直觀。缺點(diǎn),類型不做檢測(編譯不做檢測,運(yùn)行報(bào)錯(cuò))
Qt5以上支持Qt4的寫法,反之不支持。
qt, connect參數(shù),Qt::DirectConnection,Qt::QueuedConnection
connect用于連接qt的信號和槽,在qt編程過程中不可或缺。它其實(shí)有第五個(gè)參數(shù),只是一般使用默認(rèn)值,在滿足某些特殊需求的時(shí)候可能需要手動(dòng)設(shè)置。
Qt::AutoConnection: 默認(rèn)值,使用這個(gè)值則連接類型會(huì)在信號發(fā)送時(shí)決定。如果接收者和發(fā)送者在同一個(gè)線程,則自動(dòng)使用Qt::DirectConnection類型。如果接收者和發(fā)送者不在一個(gè)線程,則自動(dòng)使用Qt::QueuedConnection類型。
Qt::DirectConnection:槽函數(shù)會(huì)在信號發(fā)送的時(shí)候直接被調(diào)用,槽函數(shù)運(yùn)行于信號發(fā)送者所在線程。效果看上去就像是直接在信號發(fā)送位置調(diào)用了槽函數(shù)。這個(gè)在多線程環(huán)境下比較危險(xiǎn),可能會(huì)造成奔潰。
Qt::QueuedConnection:槽函數(shù)在控制回到接收者所在線程的事件循環(huán)時(shí)被調(diào)用,槽函數(shù)運(yùn)行于信號接收者所在線程。發(fā)送信號之后,槽函數(shù)不會(huì)立刻被調(diào)用,等到接收者的當(dāng)前函數(shù)執(zhí)行完,進(jìn)入事件循環(huán)之后,槽函數(shù)才會(huì)被調(diào)用。多線程環(huán)境下一般用這個(gè)。
Qt::BlockingQueuedConnection:槽函數(shù)的調(diào)用時(shí)機(jī)與Qt::QueuedConnection一致,不過發(fā)送完信號后發(fā)送者所在線程會(huì)阻塞,直到槽函數(shù)運(yùn)行完。接收者和發(fā)送者絕對不能在一個(gè)線程,否則程序會(huì)死鎖。在多線程間需要同步的場合可能需要這個(gè)。
Qt::UniqueConnection:這個(gè)flag可以通過按位或(|)與以上四個(gè)結(jié)合在一起使用。當(dāng)這個(gè)flag設(shè)置時(shí),當(dāng)某個(gè)信號和槽已經(jīng)連接時(shí),再進(jìn)行重復(fù)的連接就會(huì)失敗。也就是避免了重復(fù)連接。
總結(jié)
- 上一篇: 用 FastJSON 将 JSON 字符
- 下一篇: VScode 格式化代码快捷键、修改快捷