Qt UI 文件机制

使用 Qt 设计界面程序时,若界面是静态的,可以借助 Qt Designer 进行所见即所得的界面设计。设计好界面后,在界面类中对 ui 对象进行操作非常方便。

QtCreator 自动生成的界面类

构建运行一个有 Qt 界面文件的项目时,会在程序构建目录下面生成一些前缀为 ui_ 的文件,在界面类(以 window 为例)中引用的就是对应 ui_window 文件中的内容。window.h 和 window.cpp 中的内容示例:

// window.h
namespace Ui {
class Window;
} class Window : public QWidget {
Q_OBJECT
public:
explicit Window(QWidget *parent = 0); private:
Ui::Window *ui;
}
// window.cpp
#include "window.h"
#include "ui_window.cpp" Window::Window() : QWidget(parent), ui(new Ui::Window)
{ }

由 Qt 的 moc 系统自动生成的 ui_window 中的内容示例:

QT_BEGIN_NAMESPACE

class Ui_Window
{
public:
QAction *action;
... void setupUi(QWidget *Window)
{
... retranslateUi(Window);
QMetaObject::connectSlotsByName(Window);
} void retranslateUi(QWidget *Window)
{
....
action->setText(QApplication::translate("Window", "aciton", 0));
} } namespace Ui {
class Window: public Ui_Window {};
} // namespace Ui QT_END_NAMESPACE

ui_window 文件中包含有 Ui_Window 类,还有个 Ui 命名空间,命名空间中包含有一个和界面类同名的 Window 类,而这个类是 Ui_Window 的子类。

Ui::Window 类的方法有: setupUi 和 retranslateUi,从字面上看能够知道一个是用于界面初始化的,一个是用来做多语言功能的。

分离界面和业务逻辑

Qt Designer 使得界面程序的开发变得简单,在 Designer 中拖动组件就可以快速完成界面的开发。但有些界面程序需要在界面上右键显示弹出菜单,如果能够像 Qt Designer 所作的那样,把右键菜单和具体的业务逻辑分开,那么界面类实现起来感觉就会更加流畅。(似乎没法直接用 Qt Designer 制作一个 QMenu 的 ui 文件)

自己动手写界面代码,就按照 Qt Creator 中提供的模版进行编写就可以了。将要用到的界面全都放进 ui_curve.h 中,然后在 curve.cpp 中引用 Ui::Curve。

#ifndef UI_CURVE_H
#define UI_CURVE_H #include <QVariant>
#include <QApplication>
#include <QWidget>
#include <QGridLayout>
#include <QMenu>
#include <QAction>
// 界面类 class Ui_Curve{
public:
QGridLayout *mainLayout;
QMenu *mainMenu;
QMenu *subCurveMenu;
QAction *autoXAxisRange;
QAction *autoYAxisRange;
QAction *saveDataAction;
QAction *xCurveAction;
QAction *yCurveAction;
QAction *zCurveAction;
QAction *subPlotAction;
QAction *resetAction;
QAction *rescaleAction;
QAction *setXRangeAction;
QAction *setYRangeAction;
QAction *unionSubYAxis;
QAction *wheelOnYOnly; void setupUi(QWidget *curve) {
if( curve->objectName().isEmpty() )
curve->setObjectName("Curve"); mainLayout = new QGridLayout();
curve->setLayout( mainLayout ); mainMenu = new QMenu( curve ); // setup Sub Curve on One plot => menu
subCurveMenu = new QMenu( curve );
xCurveAction = new QAction( curve );
xCurveAction->setData( "X" ); // used for identify
xCurveAction->setCheckable( true );
xCurveAction->setChecked( true );
subCurveMenu->addAction( xCurveAction ); yCurveAction = new QAction( curve );
yCurveAction->setData( "Y" );
yCurveAction->setCheckable( true );
yCurveAction->setChecked( true );
subCurveMenu->addAction( yCurveAction ); zCurveAction = new QAction( curve );
zCurveAction->setData( "Z" );
zCurveAction->setCheckable( true );
zCurveAction->setChecked( true );
subCurveMenu->addAction( zCurveAction ); mainMenu->addMenu( subCurveMenu );
mainMenu->setProperty( "SubCurveCount", 3 ); // display sub curve in independent widgets => action
subPlotAction = new QAction( curve );
subPlotAction->setCheckable( true );
subPlotAction->setChecked(true);
mainMenu->addAction( subPlotAction );
mainMenu->addSeparator(); resetAction = new QAction( curve );
mainMenu->addAction( resetAction );
mainMenu->addSeparator(); // rescale Y AXis => action
rescaleAction = new QAction( curve );
mainMenu->addAction( rescaleAction ); //
autoXAxisRange = new QAction( curve );
autoXAxisRange->setCheckable( true );
autoXAxisRange->setChecked( true );
mainMenu->addAction( autoXAxisRange ); autoYAxisRange = new QAction( curve );
autoYAxisRange->setCheckable( true );
autoYAxisRange->setChecked( true );
mainMenu->addAction( autoYAxisRange );
mainMenu->addSeparator(); setXRangeAction = new QAction( curve );
mainMenu->addAction( setXRangeAction );
setYRangeAction = new QAction( curve );
mainMenu->addAction( setYRangeAction ); unionSubYAxis = new QAction( curve );
unionSubYAxis->setCheckable( true );
unionSubYAxis->setChecked( true ); mainMenu->addAction( unionSubYAxis ); wheelOnYOnly = new QAction( curve );
wheelOnYOnly->setCheckable( true );
wheelOnYOnly->setChecked( true );
mainMenu->addAction( wheelOnYOnly ); mainMenu->addSeparator(); saveDataAction = new QAction( curve );
saveDataAction->setCheckable( true );
saveDataAction->setChecked( false );
mainMenu->addAction( saveDataAction ); retranslateUi( curve );
QMetaObject::connectSlotsByName(curve);
} void retranslateUi(QWidget *curve) {
subCurveMenu->setTitle(QApplication::translate("Curve", "Show Sub Curve On Main Widget", 0));
xCurveAction->setText(QApplication::translate("Curve", "Display X (red) Line", 0));
yCurveAction->setText(QApplication::translate("Curve", "Display Y (green) Line", 0));
zCurveAction->setText(QApplication::translate("Curve", "Display Z (blue) Line", 0));
subPlotAction->setText(QApplication::translate("Curve", "Display Sub Curves In Other Widgets", 0));
resetAction->setText(QApplication::translate("Curve", "Reset Timer and clear ALL points", 0));
rescaleAction->setText(QApplication::translate("Curve", "Rescale Y Axis", 0));
autoXAxisRange->setText(QApplication::translate("Curve", "Auto Set X Axis Range", 0));
autoYAxisRange->setText(QApplication::translate("Curve", "Auto Set Y Axis Range", 0));
setXRangeAction->setText(QApplication::translate("Curve", "Set X Axis Range", 0));
setYRangeAction->setText(QApplication::translate("Curve", "Set Y Axis Range", 0));
unionSubYAxis->setText(QApplication::translate("Curve", "union All three sub y axis (x-y-z)", 0));
wheelOnYOnly->setText(QApplication::translate("Curve", "Wheel Grag or Zomm On Y axis only", 0));
saveDataAction->setText(QApplication::translate("Curve", "Save All Data On Close", 0));
}
}; namespace Ui {
class Curve : public Ui_Curve {};
} #endif // UI_CURVE_H

然后在界面类中重写 mousePressEvent 事件,检测到鼠标右击后调用 ui->mainMenu->popup( event->globalPos() ); 弹出菜单。

上述文件中有两个方法值得注意:

  • QMetaObject::connectSlotsByName 这是用来自动连接信号和槽(槽的名称模式为:void on_<object name>_<signal name>(<signal parameters>);)的,但是 Ui_Curve 中我没有给各个 QAction 对象写 objectName,所以这里对 connectSlotsByName 的调用没有效果。
  • QApplication::translate 是提供翻译功能的,和 Qt 中常用的 QObject::tr 功能相同,但显然 QObject::tr 用起来更方便。

虽然编写界面代码没什么技术含量,但是更重要的事情是理解 Qt 的 UI 模型。这个模型能够将界面代码从逻辑代码中分离出来,分离后的 UI 和业务逻辑使得代码的可维护性提高,整体代码的可读性和可维护性都提高了很多。

Qt 学习(4)的更多相关文章

  1. QT学习第1天

    QT学习第一天  坚持住!! 一 Qt概述 1.Qt发展历史 (1)1991年诞生(Haavard Nord/Eirik Chambe-Eng), (2)1994年创立Troll Tech(奇趣科技) ...

  2. 【转载】分享一些Qt学习资源,欢迎下载

    资源来源:http://bbs.csdn.net/topics/390358737 经过我一翻整理,把一些我收集到的Qt学习资源分享给大家,主要适合新手,老鸟可以直接忽略我.要说明一下,很多资源都是在 ...

  3. QT学习之路--创建一个对话框

    Q_OBJECT:这是一个宏,凡是定义信号槽的类都必须声明这个宏. 函数tr()全名是QObject::tr(),被他处理过的字符串可以使用工具提取出来翻译成其他语言,也就是做国际化使用. 对于QT学 ...

  4. 转载: Qt 学习之路 2归档

    Qt 学习之路 2归档 http://www.devbean.net/2012/08/qt-study-road-2-catelog/

  5. Qt 学习资料

    Qter开源社区http://www.qter.org/ [Qt教程], 作者yafeilinux [视频] QT学习之路:从入门到精通 <C++ Qt 编程视频教程>

  6. qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果

    应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm 先看看执行效果,我用的群创7寸屏 ...

  7. Qt学习博客推荐

    附录C Qt资源 C.1 Qt 官方资源 全 球各大公司以及独立开发人员每天都在加入 Qt 的开发社区.他们已经认识到了Qt 的架构本身便可加快应用程序开发进度.这些开发人员,无论是想开发单平台软件. ...

  8. qt学习教程1.qt开发环境搭建

    qt学习教程1.qt开发环境搭建 首先下载qt 下载地址:http://download.qt.io/archive/qt/ 此教程使用的版本为5.1.1 下载好后,打开安装包,然后点下一步 选择一个 ...

  9. QT学习教程

    原地址:http://www.devbean.NET/2012/08/qt-study-road-2-catelog/ 网上看到的不错的教程 本教程以qt5为主,部分地方会涉及qt4.据说非常适合qt ...

  10. Qt学习之路

      Qt学习之路_14(简易音乐播放器)   Qt学习之路_13(简易俄罗斯方块)   Qt学习之路_12(简易数据管理系统)   Qt学习之路_11(简易多文档编辑器)   Qt学习之路_10(Qt ...

随机推荐

  1. ubuntu - 如何搜索文件?

    1.whereis 文件名 特点:快速,但是是模糊查找,例如 找 #whereis mysql 它会把mysql,mysql.ini,mysql.*所在的目录都找出来.我一般的查找都用这条命令. 2. ...

  2. ACM 离散化处理

    使用STL算法离散化: 思路:先排序,再删除重复元素,然后就是索引元素离散化后对应的值. 1.  unique():   头文件为algorithm unique的作用是“去掉”容器中相邻元素的重复元 ...

  3. AngularJS(一)理论篇

    前言 大概今年春天的时候,自己对这个词产生了兴趣,那会只是简单的查了一下,并没有深入研究过这部分知识块,现在终于开始接触这些东西. 内容 AngularJS在web应用方面是一个非常完美的JavaSc ...

  4. plsql查询结果中文乱码

    网上的教程很多,但是这里需要说明的是如果没有安装oracle客户端的情况下,该怎么修改注册表里面的oracle参数呢? 当然有些是不需要改注册表的,只需要配置环境变量就可以了,但是有的时候发现改了之后 ...

  5. Python学习过程(一)

    Hi,最近得知了有这么一种计算机语言,名字叫Python,下面对自己从零开始学习的一个记录.被大家所熟知的语言有很多种,比如说C语言 .java .C++  .C#等,以及javascri和火的一塌糊 ...

  6. window.performance

    利用window.performance查看网页性能 一般我们可以通过浏览器的调试工具-网络面板,或者代理工具查看网页加载过程中的各个阶段的耗时.而利用window.performance属性则可以获 ...

  7. Ubuntu安装SHH服务

    1.打开"终端窗口",输入"sudo apt-get update"-->回车-->"输入当前登录用户的管理员密码"--> ...

  8. 理解Javascript_01_理解内存分配

    理解Javascript_01_理解内存分配 转载自:http://www.cnblogs.com/fool/archive/2010/10/07/1845226.html   在正式开始之前,我想先 ...

  9. Web项目和Windows应用程序的配置文件

    1.Web项目,配置文件应创建在Web项目下,即使是要把配置文件作为一个单独的文件进行配置(比如log4net.config),也需要把该配置文件放在Web项目下:同理Windows应用程序的化,配置 ...

  10. Codeforces - 625B 贪心

    求最小不重复匹配次数 改最后一个字符最划算 我当时怎么就没看出来.. #include<bits/stdc++.h> using namespace std; string S,T; in ...