簡體   English   中英

為什么Qt信號的參數不能用typedef類型定義?

[英]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) )不匹配。

SIGNALSLOT本質上是字符串化宏(舊式connect的實際簽名涉及const char *或等效的東西); connect對接收到的字符串執行規范化(刪除不必要的空格, const引用和co。 - 請參閱QMetaObject::normalizedSignature - 但同樣,不知道typedef或命名空間)並嘗試將它們與找到的信號/插槽列表相匹配元對象。

反過來,這個列表是由MOC生成的,它對C ++語法和語義有相當模糊的理解,並且非常粗暴地提取信號和插槽簽名; 因此,MOC生成的字符串和放入SIGNALSLOT宏的字符串都不會識別像typedef或“等效”名稱這樣的細微之處(例如當前命名空間的本地類型,當在外部引用時,需要具有名稱空間前面添加的名稱,如果信號和插槽中有“復雜”(和非字面匹配)類型名稱,則connect將失敗。

新式(Qt5 +) connect (在@peppe的評論中提到)應該解決這些問題(並允許將信號連接到lambda等整潔的東西),但是如果你必須使用舊式connect來避免問題你應該總是以相同的方式引用類型 - 例如,如果你在信號聲明中使用typedef ,你也必須在插槽中使用它; 如果信號中有命名空間類型,則在前面加上適當的命名空間,並在插槽中執行相同操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM