亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

發布時間:2021-10-26 15:58:01 來源:億速云 閱讀:256 作者:iii 欄目:編程語言

這篇文章主要介紹“Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么”,在日常操作中,相信很多人在Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

問題代碼:

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);
};

定義了兩個信號:

  • loginResult() 這個信號采用 eResult 作為參數,而 eResult 是 Sender 類內部定義的類型;

  • otherSignal() 作為參照,使用Qt所定義的類型的信號。

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 中定義了兩個slot分別接收 Sender 的兩個信號。

在 Receiver 的構造函數中:

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)));
}

結果在運行時報錯:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

提示信號沒有連接上。

如果我們將 eResult 放到 Sender 類外面,則沒有這個問題。

這是為什么呢?

是不是只要是類內部的類型都會出錯?

為了排除是我們自定義的枚舉的原因,我們把自己定義的 eResult 改成 MyString,其它也對應改過來。

再試:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

結果還是報錯:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

這也證定了我的猜想。為是什么呢?

打開自動生成的 moc_sender.cpp 文件看看里面的內容:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

如果我們再加一個signal:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

moc_sender.cpp 中會發生什么樣的變化呢?

(1)字面量里多出兩個新的字面量。

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

(2)在 qt_meta_data_Sender 中也多出些新的描述:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

可以看出,qt_meta_data_Sender 中可以描述出一個 QObject 類有哪些信號函數。每個信號函數的返回類型與參數各為什么。

從上可以看到,qt_meta_data_Sender 中記錄的信號自定義的參數類型idx指向的是 MyString。我們在 Receiver 中 connect() 使用的是 Sender::MyString。會不會是兩者對不上號導致的呢?

如果我們改成這樣:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

把 Sender:: 前綴加上。

看看會不會成功了呢?結果沒有再報錯了。

我們再來看看 moc_sender.cpp 的變化:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

猜想:

在下面的 connect() 代碼中:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

SIGNAL() 宏把  Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么 預編譯成 "loginResult(Sender::MyString)" 的字符串。在執行時,就會拿著該字串去 Sender 對象中找信號名為 "loginResult" 參數個數只有一個,參數類型名為 "Sender::MyString" 的信號進行連接。

如果我們在 Sender 中將 loginResult 信號的參數類型寫成 MyString 而不是寫全 Sender::MyString,那么在 connect() 時,它就不能在 Sender 的 qt_meta_data_Sender 中找到這個信號,所以就失敗了。

如果我們還是采用原來的做法:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

而在 connect() 的地方,直接寫 MyString,而不寫成 Sender::MyString,如下:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

執行報錯:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

說是不兼容的參數類型。

可能 connect() 函數在入口處,就對參數signal與slot的參數類型字串進行比較,如果不一致,那么就會認為錯誤。

那反過來,我們在 connect() 時將 slot 的參數寫成:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

執行結果:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

如果我們把 Receive::onLoginResult() 的參數類型改成 MyString 呢?

如下:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么 

編譯通過,運行時 connect() 正常。

是不是它只認類型的名稱,不做類型推導呢?

我們大膽地做一個嘗試:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

我們給 MyString 亂指定一個類型。

結果編譯通過,運行時 connect() 正常。

從本質上 MyString 就是 QString 的別名。

如果在 Receive 端使用 QString 替代 MyString 是不是就不能 connect() 成功了呢?

如下修改:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

編譯正常,運行結果:

Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么

這個實驗足于證明,connect() 只管類型名稱的比效,完全不做任何的類型推導。

綜上結論:

在執行 QObject::connect() 時,它會對signal與slot參數的名稱進行對比,只有名稱完會一致的才能連接上,否會不失敗。

值得注意的是:它只管對類型的名稱進行比較,完全不會做任何的類型推導與類型檢查。

到此,關于“Qt signal函數使用類內部類型作為參數導致connect不成功的原因是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

福清市| 合川市| 芷江| 宁蒗| 射洪县| 虞城县| 绩溪县| 高台县| 阜南县| 长寿区| 平定县| 民权县| 宜君县| 大新县| 云南省| 涞水县| 崇礼县| 凤台县| 松溪县| 中方县| 靖西县| 六枝特区| 礼泉县| 岗巴县| 泸定县| 武胜县| 昌宁县| 凭祥市| 普陀区| 长子县| 普定县| 仙居县| 塘沽区| 靖西县| 阳曲县| 华宁县| 高碑店市| 奉节县| 镇宁| 新绛县| 定南县|