使用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. int main(int argc, char *argv[])
  3. {
  4. QApplication app(argc, argv);
  5. QDialog *dialog= new QDialog;  // 用于显示界面的父窗体QDialog(QWidget的子类)
  6. Ui::GotoCellDialog ui;  // 界面类,必须显示在一个QWidget(或其子类)上
  7. ui.setupUi(dialog); // 将QDialog设置为 GotoCellDialog 的父窗体,这样GotoCellDialog 里面定义的控件就会显示在QDialog窗体内
  8. dialog->show();
  9. return app.exec();
  10. }
 #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. class GoToCellDialog: public QDialog
  4. {
  5. Q_OBJECT
  6. public:
  7. explicit GoToCellDialog(QDialog *parent = 0);
  8. private slots:
  9. void on_lineEdit_textChanged();
  10. private:
  11. Ui::GoToCellDialog ui;
  12. };
#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. #include <QtGui>
  3. GoToCellDialog::GoToCellDialog(QWidget *parent)
  4. : QDialog(parent)
  5. {
  6. ui.setupUi(this);
  7. QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
  8. lineEdit->setValidator(new QRegExpValidator(regExp, this));
  9. connect(okButton, SIGNAL(clicked()), SLOT(accept()));
  10. connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));
  11. }
  12. void GoToCellDialog::on_lineEdit_textChanged()
  13. {
  14. // bool hasAcceptableInput () const
  15. // This property holds whether the input satisfies the inputMask and the validator.
  16. // By default, this property is true.
  17. okButton->setEnabled(lineEdit->hasAcceptableInput());
  18. }
#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. class GoToCellDialog: public QDialog
  6. {
  7. // 同上
  8. private:
  9. Ui::GoToCellDialog *ui;
  10. };
namespace Ui
{
class GoToCellDialog;
} // 前置声明即可,只在实现文件中包含相应的头文件 class GoToCellDialog: public QDialog
{
// 同上
private:
Ui::GoToCellDialog *ui;
};

实现文件:

  1. #include "ui_gotocelldialog.h"
  2. GoToCellDialog::GoToCellDialog(QDialog *parent) :
  3. QDialog(parent), ui(new Ui::GoToCellDialog)
  4. {
  5. ui->setupUi(this);
  6. }
  7. CalculatorForm::~CalculatorForm()
  8. {
  9. delete ui; // 切记删除,释放资源
  10. }
#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. #include <QDialog>
  4. #include "ui_gotocelldialog.h"
  5. class GoToCellDialog :  public QDialog, public Ui::GoToCellDialog
  6. {
  7. Q_OBJECT
  8. public:
  9. explicit GoToCellDialog(QWidget *parent = 0);
  10. private slots:
  11. void on_lineEdit_textChanged();
  12. };
  13. #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. #include <QtGui>
  3. GoToCellDialog::GoToCellDialog(QWidget *parent)
  4. : QDialog(parent)
  5. {
  6. this->setupUi(this); //第1个this指Ui::GoToCellDialog,第2个this指(QDialog) 即 Ui::GoToCellDialog->setupUi(QDialog)
  7. QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
  8. lineEdit->setValidator(new QRegExpValidator(regExp, this));
  9. connect(okButton, SIGNAL(clicked()), SLOT(accept()));
  10. connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));
  11. }
  12. void GoToCellDialog::on_lineEdit_textChanged()
  13. {
  14. // bool hasAcceptableInput () const
  15. // This property holds whether the input satisfies the inputMask and the validator.
  16. // By default, this property is true.
  17. okButton->setEnabled(lineEdit->hasAcceptableInput());
  18. }
#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

在Qt中如何使用QtDesigner创建的UI文件(一) (转)的更多相关文章

  1. 在Qt中如何使用QtDesigner创建的UI文件

    使用Qt有一些时间了,一直在IDE环境(qtcreator和VS2003+集成器)中使用,自然少了很多麻烦的步骤.但是在享受这种便利的同 时,我们也失去了理解更多知识背后的点滴.在IDE中,如果我们要 ...

  2. VS2015+QT环境配置后,Lauch Qt Designer打开失败,无法打开*.ui文件

    最近在VS2015上配置QT时出现了这个问题,遂百度其解决方法,解决之后记录下来.第一步: 在[解决方案资源管理器]中,右击你的 xxx.ui文件,选择[打开方式],此时列表中默认值是[ Qt des ...

  3. 使用 PySide2 开发 Maya 插件系列一:QT Designer 设计GUI, pyside-uic 把 .ui 文件转为 .py 文件

    使用 PySide2 开发 Maya 插件系列一:QT Designer 设计GUI, pyside-uic 把 .ui 文件转为 .py 文件 前期准备: 安装 python:https://www ...

  4. QT visual stuido 集成插件不能打开ui文件的解决方法(去掉xml的UTF8标记)

    QT visual stuido 集成插件不能打开ui文件的解决方法 visual studio里不能打开这个ui文件,出现warning等解决方法是:于是将<?xml version=&quo ...

  5. Qt基础——让使用Designer创建的UI也能自动适应窗口大小

    原文请看:http://www.cnblogs.com/linmeng/archive/2012/07/05/2559259.html 我们知道,通过Qt的各种Layout可以实现控件的自动布局. 但 ...

  6. QT总结第3篇:如何在QT中添加.lib,.dll还有.h文件

    因为我在工作的过程中,使用的是第三方提供的库,但是如何将这些库添加到QT的工程中,是个问题,让我恼火了很久,怎么弄都是错的. 下面,我会对这个问题,进行叙述,希望其他人第一次遇到这种问题的时候,可以轻 ...

  7. C++ QT中自定义控件的简单创建

    为了给控件添加自定义的方法以及重绘控件,我们需要自定义控件来达到自己希望的结果,网上的自定义控件文章比较少,并且过程比较粗略. 此教程以中文版的QT Creator进行介绍 首先我们创建一个新的项目, ...

  8. javaScript中利用ActiveXObject来创建FileSystemObject操作文件

    注:如果用javascript读本地文件,遇到安全问题. 需在浏览器中进行设置,如下:     工具—> Internet选项->安全->自定义级别->启用“没有标识为安全的A ...

  9. Qt中运行后台线程不阻塞UI线程的方案

    有一个想法,一个客户端,有GUI界面的同时也要向网络服务器发送本地采集的数据,通过网络发送数据的接口是同步阻塞的,需要等待服务器响应数据. 如果不采用后台线程的方案,用主UI线程关联一个定时器QTim ...

随机推荐

  1. poj 3411 Paid Roads很水的DFS

    题意:给你N 城市和M条道路,每条道路要付的钱,但是如果你在这个道路上你可以付其他道路的钱(跟走到的时候去的话不一样),问你从1走到N最少话费是多少. 直接DFS搜. 链接http://poj.org ...

  2. 【Error】IOError: [Errno 22] invalid mode ('wb') or filename

    错误描述: IOError: [Errno 22] invalid mode ('wb') or filename: 'C:\\Users\\Viral Patel\\Documents\\GitHu ...

  3. socketserver源码简介

    一.socketserver流程简介 +------------+ | BaseServer | +------------+ | v +-----------+ +----------------- ...

  4. VUE基本安装

    // 安装脚手架 cnpm install -g vue-cli // 初始化项目 vue init webpack 项目名称 // 安装依赖 cd 项目名称 cnpm i // 安装stylus c ...

  5. Access control allow origin 简单请求和复杂请求

    原文地址:http://blog.csdn.net/wangjun5159/article/details/49096445 错误信息: XMLHttpRequest cannot load http ...

  6. RabbitMQ(6) 集群部署

    单节点部署 rabbitmq单节点部署比较简单,可以使用apt-get等工具快速安装部署. wget -O- https://www.rabbitmq.com/rabbitmq-release-sig ...

  7. 【javascript基础】运算符优先级

    优先级 运算类型 关联性 运算符 1 成员运算符 从左到右 . [] new 从右到左 new 2 函数调用运算符 从左到右 () 3 自增运算符 n/a ++ 自减运算符 n/a -- 4 逻辑非运 ...

  8. 【LeetCode 100_二叉树_遍历】Same Tree

    解法一:递归 bool isSameTree(TreeNode* p, TreeNode* q) { if (p == NULL && q == NULL) return true; ...

  9. 使用JQuery Deferred对象的then() 解决多个AJAX操作顺序依赖的问题

    原文地址:http://www.2cto.com/kf/201507/424202.html 之前的文章javascript异步代码的回调地狱中提到了编写AJAX代码经常遇到的3个问题,现在我们看下如 ...

  10. three.js入门系列之视角和辅助线

    假设你已经创建好了three.js的开发环境(我是写在vue项目中的),那么接下来,从头开始演示是如何用three.js来构建3D图形的.(笔记本写的代码,屏幕小,所以为了能够整屏看到完整代码,就将字 ...