一、导读 本质上,Qt Designer的ui文件是一个以XML格式书写的文件,文件中内容描述了一个界面的widget关系树。这个文件在以下两种情况下会使用到: (1)在编译的时候,这意味着ui文件将被转换为可编译的c++代码,这个过程由 uic 完成。(2)在应用程序运行的时候,ui文件将由 QUiLoader 类处理,该类用于解析XML文件并动态构造widget树。 本文描述第一种情况:在编译的时候使用ui文件。描述ui文件背后的机制,以及如何在应用程序中使用设计好的ui文件。 二、编译过程中对ui文件的处理 在实际项目开发中,使用Qt Designer创建用户界面组件(当然也完全可以使用代码描述),并使用Qt的集成构建工具 qmake 和uic 在构建应用程序时为生成代码,这个过程是集成开发环境完成的。生成的代码包含了ui文件中描述的用户界面对象,它是一个c++结构体,包含以下几个内容:(1)指向窗体小部件、布局、布局项、按钮组和操作的指针。 (2)名为 setupUi() 的成员函数,用于在父部件上构建部件树。(3)名为 retranslateUi() 的成员函数,用于处理ui文件字符串属性的转换。 生成的代码可以在应用程序中包含,并可以直接使用。除此之外,还可以用于扩展标准小部件的子类。 了解了QtCreator对ui文件背后的处理机制,下文将来看看如何在编译构建过程中使用ui文件。 三、在编译过程中如何使用ui文件 主要有三种方法在编译过程中使用ui文件:1、直接附加、2、单继承方式、3、多继承方式。 1、直接附加:构造一个小部件作为组件的占位符,并在其中设置用户界面。 2、单继承方式:子类化Qt标准界面元素的基类(例如QWidget或QDialog),并包括ui用户界面对象的私有实例。 3、多继承方式:将ui文件的基类和表单的用户接口对象都子类化。这允许从子类的范围内直接使用ui文件中定义的小部件。 (3-1)直接附加方式 此处,创建一个名为 widget.ui 的ui文件: 为了使用直接附加的方法使用ui文件,直接在main.cpp中包含ui_widget.h文件: #include "ui_widget.h" 然后在主函数中构造一个标准的QWidget,用于创建widget小部件,我们则使用这个QWidget来托管由widget描述的用户界面ui文件,完整代码如下: #include "ui_widget.h" int main(int argc,char *argv[]) { QApplication app(argc,argv); QWidget *w = new QWidget; Ui::Widget ui; ui.setupUi(w); w->show(); return app.exec(); } 直接附加方法是一种在应用程序中快速使用组件的简单方法。但是在实际开发中,使用Qt Designer创建的组件通常需要与应用程序的其余代码进行紧密的集成。例如,上面提供的widget代码将编译并运行,但是界面中的对象之间不会进行交互。为了实现这一点,则需要使用单继承方法。 (3-2)单继承方式 使用单继承方式,需要子类化一个标准的Qt小部件,并在其中包括ui用户界面对象的私有实例。可以采取以下两种方式的任意一种: (1)成员变量方式 (2)指向成员变量的指针 『 成员变量方式 』 在这种方法中,子类化了一个Qt小部件,并从构造函数中 setupUi() 用户界面。以这种方式使用的组件将ui文件中使用的小部件和布局公开给Qt小部件子类,并提供一个标准系统,用于在用户界面和应用程序中的其他对象之间建立信号和槽函数连接。 为了确保可以正常使用用户界面,需要在子类化的Qt小部件描述文件中包含uic生成的头文件,然后引用Ui::Widget(本文是Widget.ui界面文件): 子类化了一个Qt小部件子类的构造函数通过调用ui对象的setupUi()函数来构造和配置界面中的所有小部件和布局: 这种方法的优点是:简单使用继承来提供了基于QWidget的接口,并将用户界面小部件变量封装在ui数据成员中。我们可以使用这个方法在同一个小部件中定义多个用户界面,每个界面都包含在自己的名称空间中,并可以覆盖(或组合)它们。 『 指向成员变量的指针 』 采用这种方式,对ui用户界面对象的写法上就变成了指向 Ui::Widget 的指针: 对应的源文件则是: 这种方法的优点是:用户界面对象可以预先声明,这意味着不必在头文件中包含生成的ui_Widget.h文件,然后可以在不重新编译相关源文件的情况下更改ui文件。 可见,这两种方法都能使用ui文件,但推荐使用 指向成员变量的指针 的方式使用ui文件,这也是库和大型应用程序开发的方法,况且使用QtCreator新文件创建向导添加的ui界面类则是以这种方式生成的代码。 (3-3)多继承方式 使用Qt Designer创建的ui文件可以与标准的基于QWidget的类一起子类化。通过这种方法,可以在子类的范围内直接访问ui文件中定义的所有用户界面组件,并能够使用connect()函数建立信号和槽函数连接。 本文创建了Widget.ui界面描述文件,首先则需要在子类中包含使用uic从Widget生成的头文件: #include "ui_widget.h" 接着在这个类的定义中需继承QWidget和Ui::Widget,可以私有的继承Ui::Widget,以确保用户界面对象在子类中是私有的。当然还可以将其与public或protected关键字一起继承,就像在前面的例子中可以让ui为public或protected一样。如下所示: 对应的源码文件则是: 在多继承方式中,用户界面中使用的小部件的访问方式与手工在代码中创建的小部件的一样。除此之外,我们不再需要ui前缀来访问这些小部件了。 四、总结 以上三种在进行应用程序编译时使用ui文件的方法,其目的都是以如何在应用程序设计和编写中使用UI文件中所描述的Widget为目的展开的。直接附加方法较为简单,在开发几乎不使用。单继承方式较为常用,其次是多继承方式。