Qt 是一个C++ GUI应用框架,Qt 具有良好的可移植性支持大多数桌面和移动操作系统并常用于嵌入式开发。

Qt的发行版分为商业版和开源版,提供了Qt Creator作为轻量级IDE。

Hello World!

Qt应用的UI界面设计支持xml或者Qt Designer进行可视化设计,也可以通过C++代码建立视图。

Qt中的大多数类继承自QObject(没有继承QObject的类在开发中造成了很大麻烦),QtGui编程中各种可视化组件均继承自QWidget。

每个Qt GUI应用有且只有一个顶级组件,它可以是QWidget ,QMainWindow窗口应用,QDialog (对话框)。

上述 Qt 工程包括:

  • .pro 文件 qmake配置文件

  • dialog.h头文件 声明界面方法等

  • diaglog.cpp 事件监听及相应代码

  • main.cpp 入口和主程序逻辑

除了使用Qt Designer或编辑.ui文件外,Qt可以使用C++代码控制ui组件。这里我们完全使用代码创建一个与效果相同的工程,并解释它的机制。

mainwindow. h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
//防止重复包含的哨兵,C/C++惯用 #include <QMainWindow>
//包含组件 namespace Ui { //定义namespace
class MainWindow;
} //顶级组件MainWindow的类声明
class MainWindow : public QMainWindow
{
Q_OBJECT
//Q_OBJECT宏提供了信号槽机制、国际化机制和不基于C++ RTTI的反射能力
//建议均包含此宏 public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
//构造函数与析构函数 private:
Ui::MainWindow *ui; //定义了ui作为访问接口
}; #endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
} MainWindow::~MainWindow()
{
delete ui;
}

包含mainwindow类的实现以及事件的响应代码(当然这里没有...)

注意构造函数使用了初始化列表(这种缩进容易让人晕掉...)

main.cpp:

#include "mainwindow.h"
#include <QApplication>
#include <QLabel>
#include <QPushButton>
//头文件包含 int main(int argc, char *argv[]) //main函数
{
QApplication a(argc, argv);//定义应用对象,从参数看它是支持命令行的
MainWindow w; //定义mainwindow顶级组件
QLabel *label = new QLabel("Hello World!", &w); //自定义Label组件
QPushButton *button = new QPushButton("Disp", &w);//自定义PushButton组件
w.show(); //绘制主窗口w
button -> show(); //绘制按钮
QObject::connect(button,SIGNAL(clicked()),label,SLOT(show()));
/*重点来了:信号槽
* 信号槽是Qt实现事件响应的机制,当某一组件的某事件发生时将会发出相应的信号(SIGNAL)
* 与此信号相关的槽(SLOT)将会收到该信号并响应事件
*
* connect函数则可以将信号和槽关联起来
* QObject::connect(Object *sender,Func signal,Object* reciver,Func slot)
* 信号和槽本质上都是函数,信号由组件定义,槽则由程序员定义
*/
return a.exec();
/* 运行消息循环
* 应用等待事件的发生并进行响应
*/
}

组件与布局

布局管理

与很多GUI框架一样,Qt 提供了布局(layout) 作为空间的容器 以自动地管理组件的位置。

Qt Desinger可以方便地设置布局,Qt 同样允许以C++代码创建布局:

示例1:

#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout> int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *w = new QWidget;
QLabel *label = new QLabel("Hello World!");
QPushButton *button = new QPushButton("Clear");
QHBoxLayout *layout = new QHBoxLayout;
layout ->addWidget(label);
layout ->addWidget(button);
w->setLayout(layout);
w->show();
QObject::connect(button,SIGNAL(clicked()),label,SLOT(clear()));
return a.exec();
}

示例2:

#include <QApplication>
#include <QWidget>
#include <QSpinBox>
#include <QSlider>
#include <QHBoxLayout> int main(int argc, char *argv[])
{
        QApplication app(argc, argv);
        QWidget *window = new QWidget;
        window->setWindowTitle("Enter your age");         QSpinBox *spinBox = new QSpinBox;
        QSlider *slider = new QSlider(Qt::Horizontal);
        spinBox->setRange(0, 130);
        slider->setRange(0, 130);         QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
        QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
        spinBox->setValue(35);         QHBoxLayout *layout = new QHBoxLayout;
        layout->addWidget(spinBox);
        layout->addWidget(slider);
        window->setLayout(layout);         window->show();         return app.exec();
}

以Qwidget或QDialog为顶级组件的应用可以使用上述代码创建布局,以QMainWindow为顶级组件的应用无法用这种方式来创建布局。

其它常用组件请参考Qt API文档...

组件介绍

QTimer 计时器

QTimer *timer = new QTimer(QObject *);

它可以使用start(int msec)方法来开始计时timer->start(1000);

start()函数同时还是一个槽函数。

当计时结束,timer组件将发出timeout()信号,然后开始下一轮计时。

timer -> stop();方法将阻止继续计时。

static void QTimer::singleShot(int msec, QObject receiver, SLOT());

该方法只会在第一次时间到后定向发出timeout()信号,不再继续计时。这是一个静态方法无需建立QTimer对象即可使用。

若QTimer的计时时间设为0,则当事件队列为空时发出timeout()信号。

请不要这一机制而使用多线程机制代替。

当然,QWidget子类的timerEvent()方法可以更方便的实现计时。

QWidget::startTimer(interval)实例方法用来启动计时器,每隔interval毫秒发出执行一次QWidget::timerEvent(event)方法。

菜单(QMenuBar)、工具(QToolBar)与状态栏(QStatusBar)

示例:

#include "mainwindow.h"
#include <QApplication>
#include <QMenu>
#include <QMenuBar>
#include <QToolBar>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow *w = new MainWindow; QAction *openAction = new QAction(w);
openAction ->setIconText("Open");//设置QACtion组件显示的文字
openAction -> setStatusTip("Open a File");
//设置状态栏信息,当鼠标指针指向该组件时信息会一直显示 QMenu *fileMenu = w->menuBar()->addMenu("File");//新键菜单
fileMenu -> addAction(openAction); //新键菜单项 QToolBar *toolBar = w->addToolBar("F");//新建工具栏
toolBar->addAction(openAction);//添加工具 //QStatusBar *status = w -> statusBar();
//与QMenuBar类似的函数可以获得状态栏指针 w -> show(); return a.exec();
}

标准对话框

Qt 提供了消息、打开文件、保存文件、选择颜色等标准对话框,它们可以实例化也可以通过静态函数进行调用。

  • QMessageBox 消息框
  • QFileDialog 文件对话框(获取路径而已)
  • QColorDialog 颜色对话框
  • QInputDialog 输入框
  • QPrintDialog 打印对话框

下面以QMessageBox为例说明:

通过静态函数使用对话框:

  • void QMessageBox::about(QWidget * parent, const QString & title, const QString & text)

显示关于对话框,其标题是 title、内容是 text、父窗口是 parent,对话框只有一个 OK 按钮。

  • void QMessageBox::aboutQt(QWidget * parent, const QString & title = QString())

显示关于 Qt 对话框。

  • StandardButton QMessageBox::critical(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)

显示严重错误对话框。这个对话框将显示一个红色的错误符号。我们可以通过 buttons 参数指明其显示的按钮。默认情况下只有一个 Ok 按钮,我们可以使用StandardButtons类型指定多种按钮。

  • StandardButton QMessageBox::information(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)

QMessageBox::information()函数与QMessageBox::critical()类似,不同之处在于这个对话框提供一个普通信息图标。

  • StandardButton QMessageBox::question(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = StandardButtons( Yes | No ), StandardButton defaultButton = NoButton)

QMessageBox::question()函数与QMessageBox::critical()类似,不同之处在于这个对话框提供一个问号图标,并且其显示的按钮是“是”和“否”两个。

  • StandardButton QMessageBox::warning(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)

QMessageBox::warning()函数与QMessageBox::critical()类似,不同之处在于这个对话框提供一个黄色叹号图标。

通过通过QMessageBox对象使用对话框

QMessageBox msg;
msg.setText("Hello");
msg.exec();

从示例可以看出QMessageBox需要事件循环,exec()同时也是QMessageBox()的槽函数。

更多精彩尽在API 文档...

取代标准C++的做法

QString

Qt定义了QString类作为字符串以取代C++定义的两种风格的字符串。

QString重载了"+"和"+="运算符进行字符串连接,Qt Creator也把字符串字面值当作QString来处理。

QString的sprintf()函数提供了类似C中printf()函数的作用,配合arg()函数使用以提供类型安全,不过作为GUI框架的QT这种用法较少。

对于原生C++的两种字符串+,+=运算符可以将其转换为QString并将其连接。 * QString的toStdString()实例方法和fromStdString()静态方法可将QString和std::String相互转换 *

QString::number()系列重载静态函数可以将数字转换为字符串或者使用str.setNum()完成同样转换。

因为QString::number()函数含有base参数所以可以用作进制转换。

tr.toInt(bool *),str.toDouble(bool*) 接收一个bool指针作为参数,若转换成功则返回结果并将参数设为true;否则参数则设为false。

str.mid()str.left(),str,right()函数提供截取子串功能。

str.indexof(QString sub,int from)则可以返回子串的位置。

replace()和insert()函数提供代换和插入功能。

trimmed()函数可以去掉字符串首尾的空白字符(空格,[Tab],换行符)。

simplified()函数将连续的空白字符用一个空格代替。

toUpper()和toLower()则进行大小写转换。

QByteArray

QByteArray是一个二进制数组,以字节为单位, 常用作缓冲区。

QByteArray保证结尾一定是'\0'(其内部也可存储 \0)这一特性保证它可以转换char *(建议还是用QString)。

QByteArray提供了与QString相似的API。

QVariant

它是一个包含绝大多数Qt类、C++类、C++基本类型的共用体, 可以与任意的Qt类进行转化,常用于泛型。

它被用于构建Meta - Object , 是QCore的一部分。

Qt线性容器

QVector(连续存储),QLinkedList(链式结构),QList(推荐,分页存储)API请参照文档。

type必须提供默认构造函数,复制构造函数和赋值运算符。

发布Qt应用

发布Qt 编写的软件需要以"release" 配置编译源代码,Qt Creator左下角的运行工具栏中可以更改配置,Vs在[project/项目]->[属性/properties]中进行配置。

将编译得到的二进制可执行文件与必要的支持库打包。

支持库由.pro文件中设置的模块决定,一般包含core和gui模块的Qt应用需要以下支持库文件:

  • Qt库文件[Qt\lib]

    • Qt5Core.dll

    • Qt5Gui.dll

    • Qt5Widgets.dll

  • Qt Platform插件[Qt\plugins\platforms]

复制文件夹并删除其中的.pdb文件,只保留.dll文件。

qwindows.dll】同名.dll文件中删除带有d后缀(debug模式所需)的.dll文件,如删除"qwindowsd.dll",保留"qwindows.dll"。

Desktop平台下所需的文件:

- qoffscreen.dll

- qminimal.dll
  • ICU库[Qt\bin]

ICU库用于提供对Unicode字符编码的支持

-  icudt53.dll

- icuin53.dll

- icuuc53.dll
  • C++ Runtime Library

    • msvcp120.dll

    • msvcr120.dll

  • OpenGl支持库

    • libEGL.dll
  • Windows平台相关

    • gpsvc.dll

    • kernel32.dll

其它技术

国 际化

Qt 使用Unicode编码表示字符串为国际化创造了基础,常用的有QTextCodec类以及QObject::tr()函数,后者是Qt推荐的做法。

tr函数是translation的简写,tr()函数是QObject类提供的静态函数。

tr()函数接收一个字符串作为参数,并返回翻译后的字符串。

其翻译功能支持由Meta-Object等系统提供(后台硬系列)。

r函数的参数字符串中'&'的字符可以标记其后的一个字符,并将该字符设为快捷键。

在无法使用函数的场合(如数组的初始化列表),QT_TR_NOOP()和QT_TRANSLATE_NOOP()宏可以替代tr()函数,前者接收一个字符串作为参数并将其翻译,后者可以处理多个字符串。

鉴于自动翻译发展的现状,国际化不是一个函数就能完成的,tr()函数是一个标记,国际化仍依赖人工翻译。

(1) 在工程的.pro文件中增加【TRANSLATIONS += *.ts】

*代表ts文件具体文件名,ts文件是XML编码的翻译(源)文件

(2)创建.ts文件

使用lupdate命令,参数为工程的.pro文件

这命令是更新.ts文件,避免重复翻译

(3) 使用Qt Linguist打开.ts文件,进行翻译

Qt Linguist会提出翻译建议,但是翻译工作还要人工做

使用文件->发布命令在工程目录下创建.qm文件

(4) 安装.qm文件

包含头文件【#include 】

    QApplication a(argc, argv);
QTranslator trans;
trans.load("HelloWorld.qm");
a.installTranslator(&trans);

.qm文件为动态加载的,当更换语言后只需要更新.qm文件并重新运行程序即可,无需重新编译。

Qt 多窗口程序设计

  1. 在项目上选择添加新文件,Qt -> Qt 设计师模板类

  2. 选择界面模板

  3. 选择类名,注意不要和已有类重复。

Qt Creator会自动创建响应的头文件(.h)、源文件(.cpp)和界面文件(.ui)

4)声明新的界面类

在main.cpp文件中包含新的界面类头文件

#include "mainwindow2.h"

在namespace Ui中添加新的界面类

namespace Ui {
class MainWindow;
class MainWindow2;
}

根据需要定义界面对象,在需要时调用其show()方法显示界面。

Qt 应用图标设置

运行图标的设置

应用程序在Windows平台上运行时,任务栏中会出现图标,一般窗口的左上角也会出现对应的图标,将这个图标称为运行图标。

运行图标属于整个应用,即QApplication对象,调用QApplication::setWindowIcon(QIcon(QString Path));实例方法可以设置应用图标。

文件图标的设置

可执行文件也拥有自己的图标,但这个图标由操作系统设置。

windows平台下:

首先将图标的ico文件放入工程目录中,然后定义主文件名与工程同名的.rc文件(注意不是.qrc文件)。

在文件中写入:IDI_ICON1 ICON DISCARDABLE"img.ico"

"img.ico"代表相对路径和文件名)。保存文件并重新编译就可以更新图标。

图标文件会以二进制格式写入.exe文件中,制作发布版时无需包含.rc文件和图标文件。

Qt5 编程基础的更多相关文章

  1. 第二章 Matlab面向对象编程基础

    DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...

  2. [.net 面向对象编程基础] (1) 开篇

    [.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...

  3. Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式

    前言 啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~) 本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学 ...

  4. T-Sql编程基础

    T-sql编程 入门小游戏 T-sql编程基础,包括声明变量,if判断,while循环,以及使用一些基本函数. 记得在学校的时候,写过一个二人对打的文字输出游戏. 上代码 alter proc usp ...

  5. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  6. 如何夯实(Java)编程基础,并深入学习和提高

    如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...

  7. Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”

    Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...

  8. LINQ to XML 编程基础

    1.LINQ to XML类 以下的代码演示了如何使用LINQ to XML来快速创建一个xml: 隐藏行号 复制代码 ?创建 XML public static void CreateDocumen ...

  9. [.net 面向对象编程基础] (2) 关于面向对象编程

    [.net 面向对象编程基础]  (2)  关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问 ...

随机推荐

  1. 记一次IIS站点出错的解决过程

    记一次IIS站点出错的解决过程 以前一直都是人家用着系统出问题了反馈过来这边改,没想到这回就发生在自己使用的过程中 问题经过 我正在执行一个操作,保存了没有返回提示,打开浏览器控制台查看网络,请求返回 ...

  2. C#存储过程调用的三个方法

    //带参数的SQL语句 private void sql_param() { SqlConnection conn = new SqlConnection("server=WIN-OUD59 ...

  3. pageadmin CMS网站制作教程:栏目单页内容如何修改

    pageadmin CMS网站制作教程:栏目单页内容如何修改 一般情况下,如公司介绍,联系方式等介绍内页面都属于单页,单页内容可以直接在栏目设置界面进行修改,如下 1.对栏目单页内容进行设置,登录后台 ...

  4. 利用nginx实现负载均衡

    1.安装nginx和tomcat 我这里是使用docker安装的.安装流程可参照 dockerfile 这里安装了两个tomcat,端口分别是42000和42001.第二个tomcat的首页随便加了些 ...

  5. 完整的REM布局的工作流程与规范

    rem从去年的手淘双11开始火起来之后一直就想去使用,但是苦于学习途径有限,工作任务也比较繁忙导致一度延后. 那么现在对相关知识的学习与初步的项目实践之后,在这里记录一下使用rem解决各屏幕适配问题. ...

  6. vmware安装——CentOS-6.5和Mysql

    1.新建虚拟机 2.安装centos6.5 3.centos设置 查看网络 4.vmware设置网络连接 关闭selinux [root@china ~]# vim /etc/selinux/conf ...

  7. windows7下部署tomcat

    需要准备的软件: 1.JDK 安装程序 2.Tomcat 安装程序 JDK安装步骤: 安装方式:使用安装程序进行安装.使用JDK文件夹,免安装,以下步骤使用的是文件夹免安装,只需配置环境变量 配置环境 ...

  8. 从您的帐户中删除 App 及 iTunes Connect 开发人员帮助

    iTunes Connect 开发人员帮助 从您的帐户中删除 App 删除您不想继续销售或提供下载,且不会再重新使用其名称的 App.如果您的 App 至少有一个获准的版本,且最新版本处于下列状态之一 ...

  9. 【ROS系列】使用QT编写ROS订阅、发布程序

    Linux下一直使用QT进行开发,支持cmake使得很容易导入其他工程.学习ROS过程中,很多函数名称难记,使用QT不仅可以提示补全,还为了以后开发GUI方便吧. 1.安装ros_qtc_plugin ...

  10. 八、Linux上常用网络操作

    1. 主机名配置 hostname 查看主机名 hostname xxx 修改主机名 重启后无效 如果想要永久生效,可以修改/etc/sysconfig/network文件 2. IP地址配置 set ...