這篇文章主要介紹“Qt signal函數(shù)使用類(lèi)內(nèi)部類(lèi)型作為參數(shù)導(dǎo)致connect不成功的原因是什么”,在日常操作中,相信很多人在Qt signal函數(shù)使用類(lèi)內(nèi)部類(lèi)型作為參數(shù)導(dǎo)致connect不成功的原因是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Qt signal函數(shù)使用類(lèi)內(nèi)部類(lèi)型作為參數(shù)導(dǎo)致connect不成功的原因是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、鯉城網(wǎng)絡(luò)推廣、重慶小程序開(kāi)發(fā)公司、鯉城網(wǎng)絡(luò)營(yíng)銷(xiāo)、鯉城企業(yè)策劃、鯉城品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供鯉城建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
問(wèn)題代碼:
sender.h
class Sender : public QObject { Q_OBJECT public: explicit Sender(QObject *parent = nullptr); enum eResult { kSuccess, kFail, }; signals: void loginResult(eResult result); void otherSignal(QString str); };
定義了兩個(gè)信號(hào):
loginResult() 這個(gè)信號(hào)采用 eResult 作為參數(shù),而 eResult 是 Sender 類(lèi)內(nèi)部定義的類(lèi)型;
otherSignal() 作為參照,使用Qt所定義的類(lèi)型的信號(hào)。
receiver.h
class Receiver : public QObject { Q_OBJECT public: explicit Receiver(QObject *parent = nullptr); signals: public slots: void onLoginResult(Sender::eResult result); void onOtherSignal(QString str); private: Sender *sender_; };
在 Receiver 中定義了兩個(gè)slot分別接收 Sender 的兩個(gè)信號(hào)。
在 Receiver 的構(gòu)造函數(shù)中:
Receiver::Receiver(QObject *parent) : QObject(parent) , sender_(new Sender()) { connect(sender_, SIGNAL(loginResult(Sender::eResult)), this, SLOT(onLoginResult(Sender::eResult))); connect(sender_, SIGNAL(otherSignal(QString)), this, SLOT(onOtherSignal(QString))); }
結(jié)果在運(yùn)行時(shí)報(bào)錯(cuò):
提示信號(hào)沒(méi)有連接上。
如果我們將 eResult 放到 Sender 類(lèi)外面,則沒(méi)有這個(gè)問(wèn)題。
這是為什么呢?
是不是只要是類(lèi)內(nèi)部的類(lèi)型都會(huì)出錯(cuò)?
為了排除是我們自定義的枚舉的原因,我們把自己定義的 eResult 改成 MyString,其它也對(duì)應(yīng)改過(guò)來(lái)。
再試:
結(jié)果還是報(bào)錯(cuò):
這也證定了我的猜想。為是什么呢?
打開(kāi)自動(dòng)生成的 moc_sender.cpp 文件看看里面的內(nèi)容:
如果我們?cè)偌右粋€(gè)signal:
moc_sender.cpp 中會(huì)發(fā)生什么樣的變化呢?
(1)字面量里多出兩個(gè)新的字面量。
(2)在 qt_meta_data_Sender 中也多出些新的描述:
可以看出,qt_meta_data_Sender 中可以描述出一個(gè) QObject 類(lèi)有哪些信號(hào)函數(shù)。每個(gè)信號(hào)函數(shù)的返回類(lèi)型與參數(shù)各為什么。
從上可以看到,qt_meta_data_Sender 中記錄的信號(hào)自定義的參數(shù)類(lèi)型idx指向的是 MyString。我們?cè)?Receiver 中 connect() 使用的是 Sender::MyString。會(huì)不會(huì)是兩者對(duì)不上號(hào)導(dǎo)致的呢?
如果我們改成這樣:
把 Sender:: 前綴加上。
看看會(huì)不會(huì)成功了呢?結(jié)果沒(méi)有再報(bào)錯(cuò)了。
我們?cè)賮?lái)看看 moc_sender.cpp 的變化:
猜想:
在下面的 connect() 代碼中:
SIGNAL() 宏把 預(yù)編譯成 "loginResult(Sender::MyString)" 的字符串。在執(zhí)行時(shí),就會(huì)拿著該字串去 Sender 對(duì)象中找信號(hào)名為 "loginResult" 參數(shù)個(gè)數(shù)只有一個(gè),參數(shù)類(lèi)型名為 "Sender::MyString" 的信號(hào)進(jìn)行連接。
如果我們?cè)?Sender 中將 loginResult 信號(hào)的參數(shù)類(lèi)型寫(xiě)成 MyString 而不是寫(xiě)全 Sender::MyString,那么在 connect() 時(shí),它就不能在 Sender 的 qt_meta_data_Sender 中找到這個(gè)信號(hào),所以就失敗了。
如果我們還是采用原來(lái)的做法:
而在 connect() 的地方,直接寫(xiě) MyString,而不寫(xiě)成 Sender::MyString,如下:
執(zhí)行報(bào)錯(cuò):
說(shuō)是不兼容的參數(shù)類(lèi)型。
可能 connect() 函數(shù)在入口處,就對(duì)參數(shù)signal與slot的參數(shù)類(lèi)型字串進(jìn)行比較,如果不一致,那么就會(huì)認(rèn)為錯(cuò)誤。
那反過(guò)來(lái),我們?cè)?connect() 時(shí)將 slot 的參數(shù)寫(xiě)成:
執(zhí)行結(jié)果:
如果我們把 Receive::onLoginResult() 的參數(shù)類(lèi)型改成 MyString 呢?
如下:
編譯通過(guò),運(yùn)行時(shí) connect() 正常。
是不是它只認(rèn)類(lèi)型的名稱(chēng),不做類(lèi)型推導(dǎo)呢?
我們大膽地做一個(gè)嘗試:
我們給 MyString 亂指定一個(gè)類(lèi)型。
結(jié)果編譯通過(guò),運(yùn)行時(shí) connect() 正常。
從本質(zhì)上 MyString 就是 QString 的別名。
如果在 Receive 端使用 QString 替代 MyString 是不是就不能 connect() 成功了呢?
如下修改:
編譯正常,運(yùn)行結(jié)果:
這個(gè)實(shí)驗(yàn)足于證明,connect() 只管類(lèi)型名稱(chēng)的比效,完全不做任何的類(lèi)型推導(dǎo)。
綜上結(jié)論:
在執(zhí)行 QObject::connect() 時(shí),它會(huì)對(duì)signal與slot參數(shù)的名稱(chēng)進(jìn)行對(duì)比,只有名稱(chēng)完會(huì)一致的才能連接上,否會(huì)不失敗。
值得注意的是:它只管對(duì)類(lèi)型的名稱(chēng)進(jìn)行比較,完全不會(huì)做任何的類(lèi)型推導(dǎo)與類(lèi)型檢查。
到此,關(guān)于“Qt signal函數(shù)使用類(lèi)內(nèi)部類(lèi)型作為參數(shù)導(dǎo)致connect不成功的原因是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!