[英]why Qt signals' arguments can't be defined with typedef types?
對於Qt5 / c ++ 11項目,我使用了一個QMediaPlayer對象(名為audio_player)及其positionChanged()信號:
這段代碼還可以:
connect(this->audio_player,
SIGNAL(positionChanged(qint64)),
this,
SLOT(audio_position_changed(qint64)));
但是這個不起作用:
typedef PosInAudio qint64;
connect(this->audio_player,
SIGNAL(positionChanged(PosInAudio)),
this,
SLOT(audio_position_changed(PosInAudio)));
在運行時我得到消息“QObject :: connect:沒有這樣的信號QMediaPlayer :: positionChanged(PosInAudio)”
我很困惑地看到即使用#define定義的類型也不行:
#define PosInAudio qint64
connect(this->audio_player,
SIGNAL(positionChanged(PosInAudio)),
this,
SLOT(audio_position_changed(PosInAudio)));
(與上面相同的錯誤信息)
這是預期的行為嗎? 或者我犯了錯誤?
如上所述(感謝Matteo Italia),如果您使用此處描述的Qt5新信號槽語法,一切都可以。
問題產生於舊式connect
實際上比較字符串以匹配信號和插槽,這里是信號聲明中使用的簽名( void positionChanged(qint64)
)和connect
調用中使用的簽名( void positionChanged(PosInAudio)
如果你只是比較字符串, void positionChanged(PosInAudio)
)不匹配。
SIGNAL
和SLOT
本質上是字符串化宏(舊式connect
的實際簽名涉及const char *
或等效的東西); connect
對接收到的字符串執行規范化(刪除不必要的空格, const
引用和co。 - 請參閱QMetaObject::normalizedSignature
- 但同樣,不知道typedef
或命名空間)並嘗試將它們與找到的信號/插槽列表相匹配元對象。
反過來,這個列表是由MOC生成的,它對C ++語法和語義有相當模糊的理解,並且非常粗暴地提取信號和插槽簽名; 因此,MOC生成的字符串和放入SIGNAL
和SLOT
宏的字符串都不會識別像typedef
或“等效”名稱這樣的細微之處(例如當前命名空間的本地類型,當在外部引用時,需要具有名稱空間前面添加的名稱,如果信號和插槽中有“復雜”(和非字面匹配)類型名稱,則connect
將失敗。
新式(Qt5 +) connect
(在@peppe的評論中提到)應該解決這些問題(並允許將信號連接到lambda等整潔的東西),但是如果你必須使用舊式connect
來避免問題你應該總是以相同的方式引用類型 - 例如,如果你在信號聲明中使用typedef
,你也必須在插槽中使用它; 如果信號中有命名空間類型,則在前面加上適當的命名空間,並在插槽中執行相同操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.