用designer设计的*.ui文件可以通过uic工具转换为*.h文件(在编译时也会自动生成这样一个ui_*.h文件),有了这个.h文件就可以直接按照纯C++的方式对其中的类进行调用。ui文件的使用就是利用默认工具uic自动产生一个类,然后用该类的setui函数加载界面到相应的对象上。
.ui文件的使用有三种形式:第一种是直接使用,第二种是定义一个新类,声明一个ui子对象,利用该对象来加载界面,第三种是将ui作为基类派生新的类。
借用一个例程分析如下:
工程及界面
/***************************************dialog.h********************************************/ #ifndef DIALOG_H #define DIALOG_H #include <QDialog> namespace Ui { class Dialog; }
/*为什么要使用这样一个命名空间呢?因为我们接着又要定义一个Dialog类,二者同名,所以才用了这个命名空间。此处的类Dialog继承自Ui_Dialog,属于一个前置声明,因为在dialog.h中我们有这么一句Ui::Dialog *ui; 使用了Ui::Dialog 来定义一个指针,但是这个Ui::Dialog并没有实际上进行定义(我们是在下文中的ui_dialog.h中定义的Dialog),也没有包含相关头文件,所以用了一个前置声明(关于前置声明此处略)*/
class Dialog : public QDialog { //又定义了一个Dialog类 Q_OBJECT public: Dialog(QWidget *parent = 0); ~Dialog(); protected: void changeEvent(QEvent *e); private: Ui::Dialog *ui; // 声明一个子类 private slots: void on_pushButton_clicked(); }; #endif // DIALOG_H
红色部分声明一个类,将设计出来的ui界面作为该类的一个子对象,在其构造函数中,先完成对子对象的构造,再使用子对象ui调用其setupUi(this)函数实现ui的现实。
Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); //加载界面 }
看完上面的代码,我们来分析下到底为什么要这样来使用ui文件。
在没有qtcreator之前,给了我们一个ui文件,该如何调用?
针对于ui文件,不知道大家知不知道uic这个工具,这是qt继承的一个工具,它可以利用ui生产.h文件。
uic dialog.ui –o ui_dialog.h
就生产了下面的ui_dialog.h文件:
/**************************************ui_dialog.h*******************************************/ #ifndef UI_DIALOG_H #define UI_DIALOG_H #include <QtCore/QVariant> #include <QtGui/QAction> #include <QtGui/QApplication> #include <QtGui/QButtonGroup> #include <QtGui/QDialog> #include <QtGui/QHeaderView> #include <QtGui/QLabel> #include <QtGui/QPushButton> QT_BEGIN_NAMESPACE class Ui_Dialog { public: QLabel *label; QPushButton *pushButton; void setupUi(QDialog *Dialog) { if (Dialog->objectName().isEmpty()) Dialog->setObjectName(QString::fromUtf8("Dialog")); Dialog->resize(115, 148); label = new QLabel(Dialog); label->setObjectName(QString::fromUtf8("label")); label->setGeometry(QRect(10, 30, 91, 21)); QFont font; font.setPointSize(12); font.setBold(true); font.setWeight(75); label->setFont(font); pushButton = new QPushButton(Dialog); pushButton->setObjectName(QString::fromUtf8("pushButton")); pushButton->setGeometry(QRect(20, 80, 75, 23)); retranslateUi(Dialog); QMetaObject::connectSlotsByName(Dialog); } // setupUi void retranslateUi(QDialog *Dialog) { Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", 0, QApplication::UnicodeUTF8)); label->setText(QApplication::translate("Dialog", "hello,wang", 0, QApplication::UnicodeUTF8)); pushButton->setText(QApplication::translate("Dialog", "close", 0, QApplication::UnicodeUTF8)); } // retranslateUi }; namespace Ui { class Dialog: public Ui_Dialog {}; //此处定义了命名空间,其中定义了一个Dialog类,继承自Ui_Dialog类 } // namespace Ui QT_END_NAMESPACE #endif // TT_H
通过观察我们会发现uic自动将我们设计的ui文件,生成了一个类,在此例中为class Ui_Dialog。事实上也是这样,uic会自动会利用设计好的ui生成一个包含类Ui_**的ui_**.h文件。那么在此例中,就会将我们设计好的dialog就会被uic文件解析,生成一个叫做ui_dialog.h的文件,此文件中包含Ui_Dialog的类。
那么总结出来,要让ui design设计出来的界面显示出来,只要能设法调用Ui_Dialog类的setupUi函数就行了。
一种简单的方法,直接使用,重新写一个这样的main函数。
#include <QtGui/QApplication> #include <QDialog> #include "ui_dialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Ui::Dialog ui; QDialog *d=new QDialog; ui. setupUi(d); d->show(); return a.exec(); }
第二种方法相对比较简单一点,就是将Ui::Dialog ui或Ui::Dialog *ui写成一个新定义类的一个数据成员,也就是qtcreator提供的那种方法。(也叫单继承方法,只继承了QDialog类)
#include <QDialog> #include "ui_dialog.h" class Dialog : public QDialog { Q_OBJECT public: Dialog(QWidget *parent = 0); ~Dialog(); protected: void changeEvent(QEvent *e); private: Ui::Dialog *ui; private slots: void on_pushButton_clicked(); };
这样使用的时候需要注意的是在初始化的时候要先完成子对象的初始化,在其构造函数中重写构造函数。
Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); }
第三种方法是以Ui_Dialog类为基类,派生一个新类,在该类的初始化函数中调用setupUi。(也叫多重继承方法,继承了QDialog类和Ui::Dialog类)
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include "ui_dialog.h" class Dialog : public QDialog ,public Ui::Dialog { Q_OBJECT public: Dialog(QWidget *parent = 0); };
实现如下:
#endif // DIALOG_H #include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), Ui::Dialog() { setupUi(this); }
附上一个直接使用ui_hellodialog.h的小例程
程序如下:
/**************************************ui_hellodialog.h******************************************/
/******************************************************************************** ** Form generated from reading UI file ‘hellodialog.ui‘ ** ** Created: Wed May 14 19:28:14 2014 ** by: Qt User Interface Compiler version 4.8.4 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ #ifndef UI_HELLODIALOG_H #define UI_HELLODIALOG_H #include <QtCore/QVariant> #include <QtGui/QAction> #include <QtGui/QApplication> #include <QtGui/QButtonGroup> #include <QtGui/QDialog> #include <QtGui/QHeaderView> #include <QtGui/QLabel> QT_BEGIN_NAMESPACE class Ui_HelloDialog { public: QLabel *label; void setupUi(QDialog *HelloDialog) { if (HelloDialog->objectName().isEmpty()) HelloDialog->setObjectName(QString::fromUtf8("HelloDialog")); HelloDialog->resize(400, 300); label = new QLabel(HelloDialog); label->setObjectName(QString::fromUtf8("label")); label->setGeometry(QRect(120, 120, 151, 31)); retranslateUi(HelloDialog); QMetaObject::connectSlotsByName(HelloDialog); } // setupUi void retranslateUi(QDialog *HelloDialog) { HelloDialog->setWindowTitle(QApplication::translate("HelloDialog", "Dialog", 0, QApplication::UnicodeUTF8)); label->setText(QApplication::translate("HelloDialog", "Hello World! \344\275\240\345\245\275Qt\357\274\201", 0, QApplication::UnicodeUTF8)); } // retranslateUi }; namespace Ui { class HelloDialog: public Ui_HelloDialog {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_HELLODIALOG_H
/****************************************main.cpp****************************************/
#include "ui_hellodialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QDialog w; Ui::HelloDialog ui; ui.setupUi(&w); w.show(); return a.exec(); }
引文链接: