QT 信號與槽connect


QT 信號與槽connect

QT中信號與槽的連接使用的connect函數是一個靜態函數,在類QObject中定義。這里說的是QT5環境下。更詳細的介紹可以看這里http://www.devbean.net/2012/12/how-qt-signals-and-slots-work-qt5/

本文由烏合之眾 lym瞎編,歡迎轉載 blog.cnblogs.net/oloroso
本文由烏合之眾 lym瞎編,歡迎轉載 my.oschina.net/oloroso

connect函數調用幾個限制

  • 1. 信號的發送者必須是QObject的派生類對象。不然會出現error: invalid conversion from 'XXX*' to 'const QObject*' [-fpermissive]...的錯誤。

  • 2. 回調槽函數的對象必須是QObject的派生類對象。不然會出現error: no matching function for call to 'QObject::connect(XXX*,的錯誤。這里要注意一點,信號函數無論存在與否,都不會報錯的。但是如果信號的發送者是NULL,那么會在運行的時候提示QObject::connect: Cannot connect (null)::信號函數() to 接收者::槽函數()的問題。

  • 對於1,2兩點,在connect函數調用的時候強轉類型也可以通過編譯,但是運行的時候會提示No such slot QObject::的問題。

  • 3. 槽函數所在的類的定義中必須添加宏Q_OBJECT,不然會出現QObject::connect: No such slot ...的錯誤。

    這里必須和第2點聯系起來,如果添加了Q_OBJECT宏的類不是從QObject派生的,moc生成中間文件的時候會報錯Error: Class contains Q_OBJECT macro but does not inherit from QObject

    如果添加了Q_OBJECT宏之后編譯出現了undefined reference to ‘vtable for...的錯誤,請刪除build目錄下的Makefile文件,再重新生成。

  • 4. 信號函數的signals修飾和槽函數的slots修飾其實是必須的。雖然生成的中間代碼中會去除掉。

  • 5.如果槽函數是on_控件名_信號名那么不需要主動調用connnect進行連接。
問題 原因
error: no matching function for call to 'QObject::connect(XXX*, 信號的發送者和接受者必須是QObject的派生類對象。
QObject::connect: No such slot ... 滿足面的條件后,還必須滿足槽函數所在類的定義中添加(使用)了Q_OBJECT
Error: Class contains Q_OBJECT macro but does not inherit from QObject 添加了Q_OBJECT宏的類不是從QObject派生的
undefined reference to ‘vtable for... 這是在添加了Q_OBJECT宏之后編譯出現,原因是沒有更新Makefile文件。請刪除build目錄下的Makefile文件,再使用qmake重新生成。
No matching signal for on_XXXXX_XXXXX() 槽函數是on_控件名_信號名形式,又顯示的調用了connect進行連接,就會在運行時出現這個,但是沒有什么關系。

connect函數代碼

connect是一個模板函數,但是對參數的類型是有要求的。
這個函數的返回值是QMetaObject::Connection類型的。

 1 //Connect a signal to a pointer to qobject member function
 2 //連接一個信號到 qobject 成員函數的指針
 3 
 4 template <typename Func1, typename Func2>
 5 static inline QMetaObject::Connection connect(
 6     const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
 7     Func1 signal,
 8     const typename QtPrivate::FunctionPointer<Func2>::Object *receiver,
 9     Func2 slot,Qt::ConnectionType type = Qt::AutoConnection
10     )
11 {
12     typedef QtPrivate::FunctionPointer<Func1> SignalType;
13     typedef QtPrivate::FunctionPointer<Func2> SlotType;
14 
15     //檢查信號類是否有Q_OBJECT宏
16     Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
17                       "No Q_OBJECT in the class with the signal");
18 
19     //compilation error if the arguments does not match.
20     //如果參數不匹配的編譯錯誤。
21     //槽函數需要的參數比信號函數提供多。
22     Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount),
23                       "The slot requires more arguments than the signal provides.");
24     //信號函數和槽函數的參數不是兼容的。
25     Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
26                       "Signal and slot arguments are not compatible.");
27     //信號函數返回類型是槽函數的不兼容的返回類型。
28     Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value),
29                       "Return type of the slot is not compatible with the return type of the signal.");
30 
31     const int *types = 0;
32     if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
33         types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
34 
35     //QObject::connectImpl是用於執行連接的私有內部函數。
36     //槽函數的包裝器,用於輔助調用該槽函數。
37     return connectImpl(sender, reinterpret_cast<void **>(&signal),
38                        receiver, reinterpret_cast<void **>(&slot),
39                        new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
40                        typename SignalType::ReturnType>(slot),
41                        type, types, &SignalType::Object::staticMetaObject);
42 }

 


免責聲明!

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



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