在Qt中如何使用QtDesigner建立的UI檔案(一)

來源:互聯網
上載者:User
文章目錄
  • Reacting to Language Changes

        使用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)。

 #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

#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

#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(){    // boolhasAcceptableInput () 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;

因此,相應的標頭檔中只要前置聲明即可:

namespace Ui {     class GoToCellDialog; } // 前置聲明即可,只在實現檔案中包含相應的標頭檔 class GoToCellDialog: public QDialog{       // 同上  private:        Ui::GoToCellDialog *ui; };

實現檔案:

#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類多重派生。看代碼就清楚了:

標頭檔:

#ifndef GOTOCELLDIALOG_H#define GOTOCELLDIALOG_H#include <QDialog>#include "ui_gotocelldialog.h"class GoToCellDialog :  public QDialog, public Ui::GoToCellDialog{    Q_OBJECTpublic:    explicit GoToCellDialog(QWidget *parent = 0);private slots:    void on_lineEdit_textChanged();};#endif // GOTOCELLDIALOG_H

實現檔案:

#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(){    // boolhasAcceptableInput () 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:

 

 void CalculatorForm::changeEvent(QEvent *e) {     QWidget::changeEvent(e);     switch (e->type()) {     case QEvent::LanguageChange:         ui->retranslateUi(this);         break;     default:         break;    } }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.