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