对于Qt5 / c ++ 11项目,我正在使用带有其positionChanged()信号的QMediaPlayer对象(名为audio_player):
这段代码可以:
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)
)中使用的签名不匹配。只是比较字符串。
在SIGNAL
和SLOT
基本上字符串化宏(旧式的实际签名connect
涉及const char *
或等效的东西); connect
对接收的字符串执行规范化(删除不必要的空格,const
引用和co。-参见QMetaObject::normalizedSignature
-但又一次,不了解typedef
s或名称空间),并尝试将它们与元对象中找到的信号/插槽列表进行匹配。
反过来,该列表是由MOC生成的,MOC对C ++语法和语义有相当模糊的理解,并且非常残酷地提取信号和插槽签名。因此,MOC产生的字符串以及放入SIGNAL
和SLOT
宏中的内容都不知道诸如typedef
s或“等效”名称之类的微妙之处(例如,当前名称空间的局部类型,当在外部引用时,名称必须以名称空间),因此connect
如果您在信号和插槽中使用了“复杂的”(非文字匹配)类型名称,则会失败。
新样式(Qt5 +)connect
(在@peppe的注释中提到)应该可以解决这些问题(并允许将信号连接到lambda等整洁的东西),但是如果您必须使用旧样式connect
s来避免出现问题,则应该始终以相同的方式引用类型-例如,如果typedef
在信号声明中使用a ,则也必须在插槽中使用它;如果信号中有命名空间类型,请在它们前面加上足够的命名空间,并在插槽中进行相同的操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句