【Qt】信號槽的三種連接語法
實現(xiàn)觀察者模式,可以使用函數(shù)回調(diào),但注冊回調(diào)函數(shù)有一定局限,安全性也沒有保證。所以一定程度上可以說 Qt 信號槽是對回調(diào)機(jī)制進(jìn)行了封裝。
Qt 的信號槽能夠連接(connect) 和編譯通過,需要滿足兩個條件
- 信號的參數(shù)個數(shù)大于等于槽函數(shù)
- 信號槽的參數(shù)個數(shù)相同的部分,參數(shù)類型必須一一對應(yīng)
創(chuàng)建信號槽連接,有以下三種方式
1. 使用 ui 界面控件
第一種,使用 ui 界面上的控件,通過右鍵 -> 轉(zhuǎn)到槽,則會在對應(yīng)界面的 cpp 生成類似以下函數(shù)名稱的代碼
void MainWindow::on_pushButton_clicked()
{
}
on_WidgetName_SignalName
on + 控件名稱 + 信號名稱
此種方式生成槽函數(shù),編譯時不進(jìn)行檢查,在運(yùn)行時連接,通過 Qt 自身 moc (meta object compiler) 系統(tǒng)的反射機(jī)制來連接兩個函數(shù)。
所以在控件名稱修改時,在運(yùn)行時會提示連接失敗。
另一個缺陷是這種連接方式也不方便維護(hù),連接(connect)和解除連接(disconnect)都不在可控范圍內(nèi)。
2. Qt4 的連接語法
第二種方式,使用 Qt4 語法的連接,也就是使用宏擴(kuò)展, 本質(zhì)上還是利用字符串的反射機(jī)制,示例:
connect(sender, SIGNAL(sigfunc()), receiver, SLOT((slotfunc()));
connect 的四個參數(shù)為:發(fā)送者對象指針,SIGNAL(發(fā)送者信號函數(shù)),接收者對象指針,SLOT(接收者槽函數(shù))
如果查看 SIGNAL
, SLOT
這兩個宏的實現(xiàn),就可以注意到這兩個宏是將函數(shù)名稱轉(zhuǎn)換為字符串
#ifndef QT_NO_META_MACROS
#ifndef QT_NO_DEBUG
#define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
#ifndef QT_NO_KEYWORDS
# define METHOD(0) qFlagLocation("0"#a QLOCATION)
#endif
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
#else
# ifndef QT_NO_KEYWORDS
# define METHOD(a) "0"#a
# endif
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
#endif
#
號用于將其后面的宏參數(shù)進(jìn)行字符串化, 也就是說對它之后的變量通過替換后再其左右各加上一個雙引用。
slot 槽函數(shù)以 “1” 打頭,signal 信號函數(shù)以 “2” 打頭。QT_STRINGIFY
宏的定義也是單井號的使用
#define QT_STRINGIFY2(x) #x
#define QT_STRINGIFY(x) QT_STRINGIFY2(x)
但相較第一種方式,此種方式編譯階段做了字符串形式的參數(shù)一致性檢查。
缺點是無法確認(rèn)類中是否包含此函數(shù),可以在兩個宏中放入兩個參數(shù)匹配但根本不存在的函數(shù),一樣能在編譯期間順利通過編譯檢查,卻在運(yùn)行時提示連接失敗。
3. Qt5 的連接語法
第三種,Qt5 中提供了函數(shù)指針形式的 connect 語法,示例:
connect(sender, &Sender::signal, receiver, &Receiver::slot);
類名加函數(shù)取地址,確保了編譯器檢查信號與槽函數(shù)是否匹配,可以減少運(yùn)行時出現(xiàn)連接失敗的情況。
還有一種 lambda 表達(dá)式的變體,也是使用函數(shù)指針的方式來連接
connect(sender, &Sender::signal, [](){
//... implement of slot
});
但 Qt5 語法中如果出現(xiàn)信號或槽函數(shù)重載,或兩者都有重載的情況下,connect 不會智能匹配,重載情況下直接使用,編譯會報錯,錯誤信息如下:
no matching member function for call to 'connect'
調(diào)用 connect 沒有匹配的成員函數(shù)
可以使用 Qt 的 QOverload 來處理,假如有以下信號和槽函數(shù)
signals:
void sigfunc(int);
void sigfunc(QString);
//...
public slots:
void slotfunc(int);
void slotfunc(QString);
連接時可以使用QOverload<T>::of
,示例:
connect(sender, QOverload<int>::of(&Sender::sigfunc),
receiver, QOverload<int>::of(&Receiver::slotfunc));
和文章來源:http://www.zghlxwxcb.cn/news/detail-642985.html
connect(sender, QOverload<QString>::of(&Sender::sigfunc),
receiver, QOverload<QString>::of(&Receiver::slotfunc));
來分別連接信號和槽函數(shù)的重載 (int, QString)文章來源地址http://www.zghlxwxcb.cn/news/detail-642985.html
到了這里,關(guān)于【Qt】信號槽的三種連接語法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!