Qt 信號和槽異常: QObject::connect: No Such slot baseClassName::subClassfunction() in ......


2019-08-14起筆

小熊的情況描述:

    父類A繼承自QWidget,所以父類A自動添加了Q_OBJECT。  子類B繼承自父類A,子類B沒有添加Q_OBJECT。在子類B中給動態創建的控件添加事件和槽。編譯通過,無警告,無錯誤。運行時,應用程序輸出欄顯示:QObject::connect: No Such slot ......

網上扒拉扒拉很多網友給的方案是這樣的:

以后要是碰到no such slot的問題
1、添加頭文件#include<QCoreApplication>
2、看類聲明中有沒有Q_OBJECT
3、看slot函數有沒有聲明

private slots:
void xxxx();

4、查看slot有沒有出現拼寫錯誤~~~

然而,小熊並沒有從方案一受益,於是接着發現了下面這樣一個方案:

在xxx.pro文件中添加

OBJECTS_DIR  = tmp
MOC_DIR      = tmp

哈哈~百試不爽。 非常OK。

 

但是,問題接踵而至,再添加子類,子類C繼承父類A,同樣的場景,同樣的處理方法,不見效了....what???請教網友了。

2019-08-16續寫

基類B和基類C的信號和槽的關聯方式為:

connect(m_lineEditL, SIGNAL(editingFinished()), this, SLOT(slotsLineEditContentVerify()));

今天在小熊在嘗試兩種方式使用線程的時候,我發現用另一個版本的connect比上面使用SIGNAL/SLOTS宏的版本好用,因此嘗試做如下修改:

QObject::connect(m_lineEditL, &QLineEdit::editingFinished, this, &ZLayout::slotsLineEditContentVerify);

問題搞定,perfect。

回過頭來思考, 編譯錯誤提示是沒有 基類::slotsFunctiong,   而this執行對象,是從基類繼承而來的,我們又知道帶宏定義SIGNAL/SLOTS版本的connect僅僅是做函數名的字符串替換,並不會像上面第二個版本一樣進行類型檢查,所以導致了異常現象的出現。

然后把修改工程文件的事情刪掉,並不影響什么,說明不需要更改工程文件。 另外,每一個基類都應當采用第二種版本的connect。

小熊分析的真棒!!!

網友的力量真強大!!!

 

2019年08月18日續寫

重讀16日續寫的內容,冥冥之中感覺到自己的解釋不能夠清晰的說服自己。 同時,無敵小熊猜疑到另一個點,是否是在父類A中聲明一個跟基類B和基類C用到的槽函數一樣的虛槽函數,問題一樣可以解決呢,於是動手嘗試了一下,在父類A中做如下補充:

parentCalss.h

public slots:
    virtual void slotsLineEditContentVerify();

...
parentClass.cpp
void slotsLineEditContentVerify()
{
}

這種方案下,兩種connect版本都可以達到想要的效果。

通過對比,小熊再次認定第二種版本的connect好用,為啥呢,可以少做不必要的事情而達到相同的目的。至於8月18號解釋的原因小熊日后再做校准。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM