对Qt5稍有熟悉的童鞋都知道信号、槽的自动连接机制。该机制使得qt designer 设计的UI中包含的控件,可以不通过显式connect,直接和cpp中的相应槽相关联。该机制的详细文章见
http://doc.qt.io/qt-5/designer-using-a-ui-file.html#automatic-connections
简而言之,UI中的一个object name, 可以直接与code中的槽
void on_<object name>_<signal name>(<signal parameters>);
对应,这样,在利用designer 做UI的时候,就可以很方便地完成信号槽连接,无需添加任何代码。
然而,这种机制存在一个隐患,即控件重名。虽然designer 在开发一个UI文件时,会自动为同类控件的不同实例计数,然而,当一个 UI 作为widget嵌入另一个主窗口时,却不会检查控件重名。
举例而言,假设一个日期控件widget上有个按钮叫“同步”(pushButton_syn),然后,整个日期控件作为一个widget,嵌入到主窗口(Dialog)里。恰好,主窗口中有一个按钮,也叫 pushButton_syn,好了,问题出现。在主窗口构造时,调用 setUpUI() 创建各个按钮以及控件,而后调用自动连接代码:
QMetaObject::connectSlotsByName(Mydialog);
该代码会根据目前.h中定义的符合on_objname_slot 格式的槽,到界面元素里查找对应控件。是与主窗口的pushButton_syn关联,还是与日期控件中的pushButton_syn关联,完全取决于二者的创建顺序,是不靠谱的。
为了避免这个情况,建议:
1、对可重用的含有复杂子界面的widget,设计时全部使用难以发生碰撞的名字规则,比如,
pushButton_MyCtrl_syn
2、建议对很复杂的控件,不要在 designer 里做提升,而是等到程序启动后,再动态创建,可以避免很多问题。