借助Qt提供的QtUiTools模块以及其中的QUiLoader类我们可以实现在运行时获取并
加载.ui文件。我们可以使用任何QIODevice的实例来读取用户界面架构,通常使用QFile
类的实例。QUiLoader::load()方法读取了.ui文件中包含的界面架构并将它赋予一个
QWidget子类化的实例。
本节介绍的实例名为calculatorbuilder,仍然实现简单的加法计算功能,只不过是采
用动态加载.ui文件的方法完成的。
要实现动态加载ui,首先需在程序中包含QtUiTools模块的头文件:
#include<QtUiTools>
然后新建一个.qrc文件,描述.ui文件的路径:
<!DOCTYPERCC><RCCversion="1.0">
<qresourceprefix="/forms">
<file>calculatorform.ui</file>
</qresource>
</RCC>
将弹出子窗口的.ui文件放在工程目录下。
接下来,在程序的.pro文件中手动加入以下两行代码:
CONFIG+=uitools
RESOURCES+=calculatorbuilder.qrc
我们对下面的重点代码进行讲解。
QUiLoaderloader;
QFilefile(":/forms/calculatorform.ui");file.open(QFile::ReadOnly);
QWidget*formWidget= loader.load(&file,this);
file.close();
下面的例子演示了信号与槽自动关联的具体实现过程。我们只需按照下面的标准格式定
义槽函数,这之后,uic将会根据QMetaObject类制定的规则,生成界面实体类的setupUi()
函数的内容,并完成信号与槽的关联,这一过程是隐藏在背后实现的,我们也无需过多关心。
voidon_<objectname>_<signalname>(<signalparameters>);
我们通过定义私有槽函数on_okButton_clicked()即实现了OK按钮的clicked()信号和
槽的连接。
问:动态加载方式与编译时加载.ui文件的方式,在原理上有什么不同?
答:从原理上来讲,动态加载方式并不需要通过uic把.ui文件转换成C++代码,它是
程序运行时的时候使用QUiLoader类载入该文件的,而编译时加载.ui文件的方法,是需要
借助uic把.ui文件中的内容转化为C++代码的,并生成ui_xxx.h文件。就像下面这种方式:
问:使用动态加载方式时,我如何访问窗体中的各个子窗口部件呢?
答:可以通过调用全局函数qFindChild<T>()来访问这个窗体中的各个子窗口部件,举
例如下:
ui_findButton= qFindChild<QPushButton*>(this,"findButton");
ui_textEdit= qFindChild<QTextEdit*>(this,"textEdit");
ui_lineEdit= qFindChild<QLineEdit*>(this,"lineEdit");