sui*_*kan 5 c++ qt types signals
对于Qt5/c ++ 11项目,我使用了一个QMediaPlayer对象(名为audio_player)及其positionChanged()信号:
这段代码还可以:
connect(this->audio_player,
SIGNAL(positionChanged(qint64)),
this,
SLOT(audio_position_changed(qint64)));
Run Code Online (Sandbox Code Playgroud)
但是这个不起作用:
typedef PosInAudio qint64;
connect(this->audio_player,
SIGNAL(positionChanged(PosInAudio)),
this,
SLOT(audio_position_changed(PosInAudio)));
Run Code Online (Sandbox Code Playgroud)
在运行时我得到消息"QObject :: connect:没有这样的信号QMediaPlayer :: positionChanged(PosInAudio)"
我很困惑地看到即使用#define定义的类型也不行:
#define PosInAudio qint64
connect(this->audio_player,
SIGNAL(positionChanged(PosInAudio)),
this,
SLOT(audio_position_changed(PosInAudio)));
Run Code Online (Sandbox Code Playgroud)
(与上面相同的错误信息)
这是预期的行为吗?或者我犯了错误?
如上所述(感谢Matteo Italia),如果您使用此处描述的Qt5新信号槽语法,一切都可以.
问题来自于旧式connect实际上比较字符串以匹配信号和插槽的事实,这里信号声明(void positionChanged(qint64))中使用的签名和你的connect调用中使用的签名(void positionChanged(PosInAudio))如果你是只是比较字符串.
在SIGNAL和SLOT基本上字符串化宏(旧式的实际签名connect涉及const char *或等效的东西); connect对接收到的字符串执行规范化(删除不必要的空格,const引用&co. - see QMetaObject::normalizedSignature- 但同样,不知道typedefs或名称空间)并尝试将它们与元对象中找到的信号/槽列表相匹配.
反过来,这个列表是由MOC生成的,它对C++语法和语义有相当模糊的理解,并且非常粗暴地提取信号和插槽签名; 所以,无论是通过MOC也不是什么产生的串放入SIGNAL和SLOT宏都知道像微妙的typedefS或"等同"的名称(如一个类型的本地当前的命名空间,其中,引用外时,需要将其名称由前缀命名空间),所以connect如果你有"复杂"会失败(和非字面匹配),输入你的信号和插槽的名称.
新风格(Qt5 +)connect(在@peppe的评论中提到)应该解决这些问题(并允许将信号连接到lambda等简洁的东西),但是如果你必须使用旧式connects来避免问题你应该总是以相同的方式引用类型 - 例如,如果你typedef在信号声明中使用a ,你也必须在插槽中使用它; 如果信号中有命名空间类型,则在前面加上适当的命名空间,并在插槽中执行相同操作.
| 归档时间: |
|
| 查看次数: |
1345 次 |
| 最近记录: |