为什么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)
)中使用的签名不匹配,如果您只是比较字符串。
SIGNAL
和SLOT
本质上是字符串化宏(旧式connect
的实际签名涉及const char *
或等效的东西);connect
对接收到的字符串执行规范化(删除不必要的空格,const
引用&co.(参见QMetaObject::normalizedSignature
-但同样,不了解typedef
s或名称空间)并尝试将它们与元对象中找到的信号/插槽列表相匹配。
这个列表,反过来,是由MOC生成的,它对c++语法和语义有相当模糊的理解,并且非常残酷地提取信号和插槽签名;因此,MOC产生的字符串和放入SIGNAL
和SLOT
宏中的内容都没有意识到typedef
s或"等效"名称的微妙之处(例如,当前名称空间的本地类型,当在外部引用时,需要将其名称加上名称空间),因此如果您在信号和插槽中有"复杂"(非字面匹配)类型名称,connect
将失败。
新风格的(Qt5+) connect
(在@peppe的评论中提到)应该解决这些问题(并允许整洁的东西,如将信号连接到lambda),但如果你必须与旧风格的connect
一起生活以避免问题,你应该总是以相同的方式引用类型-例如,如果你在信号声明中使用typedef
,你也必须在插槽中使用它;如果在信号中有名称空间类型,请在它们前面加上适当的名称空间,并在插槽中这样做。
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 从 Typedef 数据类型中删除常量
- 使用智能指针指向 C 库中的结构,该结构通过 typedef 隐藏实现(即不完整的类型)
- 是否可以分别专注于 typedef 及其基础类型?
- 如何对绑定的成员方法进行typedef,然后将该类型用作模板参数
- 显式调用 typedef'd 类类型的析构函数的正式正确方法
- "typedef"类型名称是否可以像"struct"定义那样声明指向结构的指针?
- 使用 pybind11 绑定 typedef 类型的正确语法是什么?
- typedef 类型不匹配,将其传递到函数中
- 在swig.i文件中,如何为基于mfc的第三方dll解析ms-windows-vc++typedef类型
- STL代码typedef类型名value_type,size_type等如何工作
- 枚举类的c++typedef/类型替换
- typedef T类型::*语法
- typedef类型不清楚
- 为什么Qt信号的参数不能用typedef类型定义?
- 使用单独编译时返回一个typedef类型
- 错误:"dependent name is not a type" 。当在类中使用 typedef 类型作为返回值时,带有模板
- 无法识别.h文件中定义的typedef类型
- STL 复制在"typedef"类型的数组上失败