zoukankan      html  css  js  c++  java
  • 在Qt中如何使用QtDesigner创建的UI文件(一) (转)

    使用Qt有一些时间了,一直在IDE环境(qtcreator和VS2003+集成器)中使用,自然少了很多麻烦的步骤。但是在享受这种便利的同时,我们也失去了理解更多知识背后的点滴。在IDE中,如果我们要开发一个对话框,通常是使用 “新建—>Qt—>Qt设计师界面类” 这样IDE会自动的帮我们生成三个文件(filename.ui, filename.h,filename.cpp)。qmake也非常智能,可以自动检测到这个用户界面文件(filename.ui)并且生产适当的makefile规则。这样在编译之前,IDE会自动调用uic(Qt自带的用户界面编译器,User Interface Compiler)将界面文件(filename.ui)转换成C++代码并保存在ui_filename.h文件中。并且在另外两个C++源文件(filename.h和filename.cpp)中使用了组合(即委托或代理)的方式使用了ui_filename.h里的类(该类通常定义在命名空间Ui下)。

            如果你不主动的留心这些细节,你可能永远都不明白这些,即使使用了多年的Qt,我就是这样。一次,项目组的需求人员嫌弃我们开发人员做的界面布局不够恰当,美观。于是有了自己来开发界面的想法。很好!开发人员很快手把手的教会了需求人员用Qt Designer设计窗体界面,然而,等到需求人员把 pureui_filename.ui文件扔给我们开发人员使用时,我们顿时傻了眼,怎么用?于是使用了一个最愚蠢当然也是最简单的办法: 还是和之前一样,通过IDE“新建—>Qt—>Qt设计师界面类”生成与“pureui_filename.”同名的文件,然后用需求人员给的pureui_filename.ui替换IDE自动生成的  *.ui 文件。虽然转了一个小弯,但目的达到!

           后来想想,总觉得多少有些遗憾,于是查阅了Qt文档之Using a Designer UI File in Your Application

           在这个文档中,详细说明了在应用程序中使用UI文件的方法。

    一、直接的方法(The Direct Approach

         即把filename.ui经过uic转换后的C++代码文件ui_filename.h直接包含,使用其里面Ui命名空间下的类(名称和主窗体的objectname相同,这里假设为GoToCellDialog)。

    1. #include "ui_gotocelldialog.h"    // uic工具将gotocelldialog.ui生成的C++代码  
    2.   
    3. int main(int argc, char *argv[])  
    4. {  
    5.     QApplication app(argc, argv);  
    6.   
    7.     QDialog *dialog= new QDialog;  // 用于显示界面的父窗体QDialog(QWidget的子类)   
    8.      Ui::GotoCellDialog ui;  // 界面类,必须显示在一个QWidget(或其子类)上  
    9.      ui.setupUi(dialog); // 将QDialog设置为 GotoCellDialog 的父窗体,这样GotoCellDialog 里面定义的控件就会显示在QDialog窗体内  
    10.   
    11.      dialog->show();  
    12.     return app.exec();  
    13. }  
     #include "ui_gotocelldialog.h"    // uic工具将gotocelldialog.ui生成的C++代码
    
     int main(int argc, char *argv[])
     {
         QApplication app(argc, argv);
    
         QDialog *dialog= new QDialog;  // 用于显示界面的父窗体QDialog(QWidget的子类) 
          Ui::GotoCellDialog ui;  // 界面类,必须显示在一个QWidget(或其子类)上
          ui.setupUi(dialog); // 将QDialog设置为 GotoCellDialog 的父窗体,这样GotoCellDialog 里面定义的控件就会显示在QDialog窗体内
    
          dialog->show();
         return app.exec();
     }

    二、单继承方式(The Single Inheritance Approach)

           单继承方式是相对于后面要讲的多继承方式,单继承方式也称组合(即委托或代理)方式。单继承方式简单来说就是在代码中首先要自定义一个子类(例如下文中的GoToCellDialog类),该类要从form对应的窗体类(或其兼容的子类)派生;并用ui生成的类定义一个类里的成员变量,该成员变量可以是值也可以是指针,根据使用成员变量的形式不同,又分为成员变量和指针成员变量两种形式。这样在GoToCellDialog的构造函数中可以直接调用ui和ui中的变量和函数,使用起来很方便。

    1、使用成员变量

          即将 Ui::GotoCellDialog ui; 作为类GotoCellDialog(只继承自QDialog,单一继承)的成员变量。这里有一点值得注意的地方,就是ui文件提供的类被包含在了名为Ui的name space里,这样做的目的是将ui文件的命名空间与用户的代码分离,避免两者出现命名冲突的情况。

    头文件: gotocelldialog.h

    1. #include <QDialog>  
    2. #include "ui_gotocelldialog.h" // 因为是成员变量形式,必须包含相应的头文件  
    3.    
    4. class GoToCellDialog: public QDialog  
    5.  {  
    6.      Q_OBJECT  
    7.   
    8.  public:  
    9.     explicit GoToCellDialog(QDialog *parent = 0);  
    10.   
    11.  private slots:  
    12.      void on_lineEdit_textChanged();  
    13.   
    14.  private:  
    15.      Ui::GoToCellDialog ui;  
    16.  };  
    #include <QDialog>
    #include "ui_gotocelldialog.h" // 因为是成员变量形式,必须包含相应的头文件
     
    class GoToCellDialog: public QDialog
     {
         Q_OBJECT
    
     public:
        explicit GoToCellDialog(QDialog *parent = 0);
    
     private slots:
         void on_lineEdit_textChanged();
    
     private:
         Ui::GoToCellDialog ui;
     };
    

    实现文件: gotocelldialog.cpp

    1. #include "gotocelldialog.h"  
    2.   
    3. #include <QtGui>  
    4.   
    5. GoToCellDialog::GoToCellDialog(QWidget *parent)  
    6.     : QDialog(parent)  
    7. {  
    8.     ui.setupUi(this);    
    9.   
    10.     QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");  
    11.     lineEdit->setValidator(new QRegExpValidator(regExp, this));  
    12.   
    13.     connect(okButton, SIGNAL(clicked()), SLOT(accept()));  
    14.     connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));  
    15. }  
    16.   
    17. void GoToCellDialog::on_lineEdit_textChanged()  
    18. {  
    19.     // bool hasAcceptableInput () const  
    20.     // This property holds whether the input satisfies the inputMask and the validator.  
    21.     // By default, this property is true.  
    22.     okButton->setEnabled(lineEdit->hasAcceptableInput());  
    23. }  
    #include "gotocelldialog.h"
    
    #include <QtGui>
    
    GoToCellDialog::GoToCellDialog(QWidget *parent)
        : QDialog(parent)
    {
        ui.setupUi(this);  
    
        QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
        lineEdit->setValidator(new QRegExpValidator(regExp, this));
    
        connect(okButton, SIGNAL(clicked()), SLOT(accept()));
        connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));
    }
    
    void GoToCellDialog::on_lineEdit_textChanged()
    {
        // bool	hasAcceptableInput () const
        // This property holds whether the input satisfies the inputMask and the validator.
        // By default, this property is true.
        okButton->setEnabled(lineEdit->hasAcceptableInput());
    }

    2、使用指针成员变量        与成员变量形式相似,唯一不同的是,将Ui::GoToCellDialog声明为指针成员,即 Ui::GoToCellDialog *ui;

    因此,相应的头文件中只要前置声明即可:

    1. namespace Ui   
    2. {   
    3.     class GoToCellDialog;   
    4. // 前置声明即可,只在实现文件中包含相应的头文件   
    5.   
    6. class GoToCellDialog: public QDialog  
    7. {   
    8.       // 同上   
    9.  private:   
    10.        Ui::GoToCellDialog *ui;   
    11. };  
    namespace Ui 
    { 
        class GoToCellDialog; 
    } // 前置声明即可,只在实现文件中包含相应的头文件 
    
    class GoToCellDialog: public QDialog
    { 
          // 同上 
     private: 
           Ui::GoToCellDialog *ui; 
    };
    

    实现文件:

    1. #include "ui_gotocelldialog.h"  
    2.   
    3.  GoToCellDialog::GoToCellDialog(QDialog *parent) :  
    4.      QDialog(parent), ui(new Ui::GoToCellDialog)  
    5.  {  
    6.      ui->setupUi(this);  
    7.  }  
    8.   
    9.  CalculatorForm::~CalculatorForm()  
    10.  {  
    11.      delete ui; // 切记删除,释放资源  
    12.  }  
    #include "ui_gotocelldialog.h"
    
     GoToCellDialog::GoToCellDialog(QDialog *parent) :
         QDialog(parent), ui(new Ui::GoToCellDialog)
     {
         ui->setupUi(this);
     }
    
     CalculatorForm::~CalculatorForm()
     {
         delete ui; // 切记删除,释放资源
     }

     三、多继承方式(The Multiple Inheritance Approach)         多继承方式就是自定义的类从窗体类和Ui类多重派生。看代码就清楚了:

    头文件:

    1. #ifndef GOTOCELLDIALOG_H  
    2. #define GOTOCELLDIALOG_H  
    3.   
    4. #include <QDialog>  
    5. #include "ui_gotocelldialog.h"  
    6.   
    7. class GoToCellDialog :  public QDialog, public Ui::GoToCellDialog  
    8. {  
    9.     Q_OBJECT  
    10.   
    11. public:  
    12.     explicit GoToCellDialog(QWidget *parent = 0);  
    13.   
    14. private slots:  
    15.     void on_lineEdit_textChanged();  
    16. };  
    17.   
    18. #endif // GOTOCELLDIALOG_H  
    #ifndef GOTOCELLDIALOG_H
    #define GOTOCELLDIALOG_H
    
    #include <QDialog>
    #include "ui_gotocelldialog.h"
    
    class GoToCellDialog :  public QDialog, public Ui::GoToCellDialog
    {
        Q_OBJECT
    
    public:
        explicit GoToCellDialog(QWidget *parent = 0);
    
    private slots:
        void on_lineEdit_textChanged();
    };
    
    #endif // GOTOCELLDIALOG_H
    

    实现文件:

    1. #include "gotocelldialog.h"  
    2.   
    3. #include <QtGui>  
    4.   
    5. GoToCellDialog::GoToCellDialog(QWidget *parent)  
    6.     : QDialog(parent)  
    7. {  
    8.     this->setupUi(this); //第1个this指Ui::GoToCellDialog,第2个this指(QDialog) 即 Ui::GoToCellDialog->setupUi(QDialog)  
    9.   
    10.     QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");  
    11.     lineEdit->setValidator(new QRegExpValidator(regExp, this));  
    12.   
    13.     connect(okButton, SIGNAL(clicked()), SLOT(accept()));  
    14.     connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));  
    15. }  
    16.   
    17. void GoToCellDialog::on_lineEdit_textChanged()  
    18. {  
    19.     // bool hasAcceptableInput () const  
    20.     // This property holds whether the input satisfies the inputMask and the validator.  
    21.     // By default, this property is true.  
    22.     okButton->setEnabled(lineEdit->hasAcceptableInput());  
    23. }   
    #include "gotocelldialog.h"
    
    #include <QtGui>
    
    GoToCellDialog::GoToCellDialog(QWidget *parent)
        : QDialog(parent)
    {
        this->setupUi(this); //第1个this指Ui::GoToCellDialog,第2个this指(QDialog) 即 Ui::GoToCellDialog->setupUi(QDialog)
    
        QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
        lineEdit->setValidator(new QRegExpValidator(regExp, this));
    
        connect(okButton, SIGNAL(clicked()), SLOT(accept()));
        connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));
    }
    
    void GoToCellDialog::on_lineEdit_textChanged()
    {
        // bool	hasAcceptableInput () const
        // This property holds whether the input satisfies the inputMask and the validator.
        // By default, this property is true.
        okButton->setEnabled(lineEdit->hasAcceptableInput());
    } 

    PS:关于UI界面中的国际化

           如果用户界面语言发送了改变,Qt通过发送 QEvent::LanguageChange 事件通知应用程序。为了调用 retranslateUi() 函数以达到切换语言的目的,我们需要重新实现界面类里面的QWidget::changeEvent() 事件处理函数。

    Reacting to Language Changes

    Qt notifies applications if the user interface language changes by sending an event of the type QEvent::LanguageChange. To call the member function retranslateUi() of the user interface object, we reimplement QWidget::changeEvent() in the form class, as follows:

    1. void CalculatorForm::changeEvent(QEvent *e)  
    2. {  
    3.     QWidget::changeEvent(e);  
    4.     switch (e->type()) {  
    5.     case QEvent::LanguageChange:  
    6.         ui->retranslateUi(this);  
    7.         break;  
    8.     default:  
    9.         break;  
    10.    }  
    11. }  
    12. http://blog.csdn.net/e5max/article/details/9869977
  • 相关阅读:
    两种代理模式(JDK和Cglib)实例
    打印1到最大的n位数
    二叉树的构建以及先中后序遍历
    二维数组的查找
    斐波那契递归和非递归俩种算法实例
    淘宝tairKV分布式
    OSI七层模型详解
    Spring事务配置的五种方式
    linux中cat、more、less、tail、head命令的区别
    跨域的理解与实现
  • 原文地址:https://www.cnblogs.com/xihong2014/p/6528137.html
Copyright © 2011-2022 走看看