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號解釋的原因小熊日后再做校准。
