赞
踩
Qt(官方发音 [kju:t],音同 cute)是一个跨平台的 C++ 开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序
,当然也可以开发不带界面的命令行(Command User Interface,CUI)程序。
Qt4 时代的主流就是传统部件(或叫控件)编程,所用的语言一般是 C++。 Qt5 诞生之时,正是手机移动设备蓬勃发展的时候,而传统的 C++ 部件编写的界面对手机应用程序非常方便,比如手机屏幕显示随意翻转, 这在传统桌面程序里基本遇不到,谁会将 22 寸显示器翻过来转过去呢。
为了适应手机移动应用开发, Qt5 将 QML 脚本编程提到与传统 C++ 部件编程相同的高度,力推 QML 界面编程,当然 QML 主要用于手机移动应用程序。 QML 包含大量使用手机移动设备的功能模块,比如基本部件(QtQuick 模块)、GPS 定位、渲染特效、蓝牙、NFC、WebkKit 等等。
时代在变化,C++ 标准也在前进。C++ 正式公布标准有 C++98、C++03、C++11。最新的 C++11 标准是2011年8月12日公布的,在公布之前该标准原名为 C++0x 。这是一次较大的修订和扩充,建议读者专门学一下。
Qt 从 4.8 版本就开始用 C++11 新特性了。编译器里面开始支持 C++11 的版本是 MSVC 2010、GCC 4.5、Clang 3.1,这之后版本的编译器都在逐步完善对 C++11 的支持,现在新版本编译器对新标准的支持都比较全面了。
Qt 官方在编译 Qt5 库的时候都是开启 C++11 特性的,如果我们要在自己项目代码启用新标准,需要在 .pro 文件里面添加一行:
目录 | 说明 |
---|---|
archive | 各种 Qt 开发工具安装包,新旧都有(可以下载 Qt 开发环境和源代码)。 |
community_releases | 社区定制的 Qt 库,Tizen 版 Qt 以及 Qt 附加源码包。 |
development_releases | 开发版,有新的和旧的不稳定版本,在 Qt 开发过程中的非正式版本。 |
learning | 有学习 Qt 的文档教程和示范视频。 |
ministro | 迷你版,目前是针对 Android 的版本。 |
official_releases | 正式发布版,是与开发版相对的稳定版 Qt 库和开发工具(可以下载Qt开发环境和源代码)。 |
online | Qt 在线安装源。 |
snapshots | 预览版,最新的开发测试中的 Qt 库和开发工具。 |
//换成自己的安装目录
D:\it\qt5.9.8\5.9.8\mingw53_32\bin
D:\it\qt5.9.8\Tools\mingw530_32\bin
安装好后,在win开始页面会有很多应用。介绍如下:
程序 | 说明 |
---|---|
Qt Creator 4.6.2 (Enterprise) | Qt 的集成开发环境,本教程就使用它来创建和管理 Qt 项目。 |
Assistant(Qt 助手) | 用来查看帮助文档,已被集成在 Qt Creator 中。 |
Designer(Qt 设计师) | 图形界面可视化编辑工具,已被集成在 Qt Creator 中,在 Qt Creator 中编辑或创建界面文件时,就可以自动打开。 |
Linguist(Qt 语言家) | 多国语言翻译支持工具,可以用来编辑语言资源文件,在开发多语言界面的应用程序时会用到。 |
Qt 5.11.1 for Desktop (MinGW 5.3.0 32bit) | Qt 命令行工具,用来配置 Qt 开发环境(主要是设置 PATH 变量)。 |
找到Qt Creator
并打开。
qt 框架封装了打印日志的方法,在QDebug类中。使用方法跟cout类似。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> //导入日志包 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), //这个表示对属性ui进行初始化 初始值为:new Ui::MainWindow。用逗号分割,后面可以初始化很多属性 ui(new Ui::MainWindow) { // 将 mainwindow.ui 的实例对象和 当前类的对象进行关联(解析 mainwindow.ui),将这个代码放最前面 ui->setupUi(this); //其他组件和业务代码 //一共有四种日志级别。 qDebug()<< "hello world!"<<"——————debug级别。"; //注意是qDebug() ,不是qDebug qWarning() << "Warning:" << "错误级别。"; qInfo() << "qInfo:" << "正常输出级别。"; qCritical() << "qCritical:" ; } MainWindow::~MainWindow() { delete ui; }
当更改代码后需要重新构建项目,代码才会是生效。
需要哪个方法就点进去看,看不懂可以去翻译一下。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QByteArray> // 导入字符串 #include <QString> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { // 将 mainwindow.ui 的实例对象和 当前类的对象进行关联(解析 mainwindow.ui),将这个代码放最前面 ui->setupUi(this); //其他组件和业务代码 // 使用无参构造创建一个类 QByteArray s; s.append("lihua"); qDebug()<<s; QByteArray s1("my name is "); s1.append("lihua"); qDebug()<<s1; QString str("123"); str.append("-456"); qDebug()<<str; } MainWindow::~MainWindow() { delete ui; }
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPoint> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个坐标点A,并调用方法设置坐标点的x、y轴 QPoint pointA; pointA.setX(10); pointA.setY(20); //调用有参构造器创建一个坐标点 QPoint pointB(40,80); //无参构造器默认x、y轴为(0,0) QPoint pointC; //获取坐标点的x、y轴的值。 qDebug()<< pointA.x(); qDebug()<< pointB.y(); qDebug()<<"x=" <<pointC.x()<<"y="<<pointC.y(); } MainWindow::~MainWindow() { delete ui; }
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPoint> //坐标 #include <QDebug> #include <QLine> //直线,由两个坐标点构成 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个坐标点A,并调用方法设置坐标点的x、y轴 QPoint pointA; pointA.setX(10); pointA.setY(20); //调用有参构造器创建一个坐标点 QPoint pointB(40,80); //无参构造器默认x、y轴为(0,0) QPoint pointC; //获取坐标点的x、y轴的值。 qDebug()<< pointA.x(); qDebug()<< pointB.y(); qDebug()<<"x=" <<pointC.x()<<"y="<<pointC.y(); //QLine() //QLine(const QPoint &p1, const QPoint &p2) //QLine(int x1, int y1, int x2, int y2) QLine line(pointC,pointA); qDebug() << "直线的中点"<<line.center().x()<<","<<line.center().y(); } MainWindow::~MainWindow() { delete ui; }
QSize类使用整数点精度定义二维对象的大小。
尺寸由宽度()和高度()指定。它可以在构造函数中设置,并使用setWidth()、setHeight()或scale()函数或算术运算符进行更改。还可以通过使用rwidth()和rheight()函数检索对宽度和高度的引用来直接操作大小。最后,可以使用transpare()函数交换宽度和高度。
isValid()函数确定大小是否有效(有效大小的宽度和高度均大于或等于零)。如果宽度和高度中的任何一个小于或等于零,isEmpty()函数将返回true,而只有当宽度和高度都为零时,isNull()函数才返回true。
使用expandedTo()函数检索一个大小,该大小包含此大小和给定大小的最大高度和宽度。类似地,boundedTo()函数返回一个大小,该大小包含此大小和给定大小的最小高度和宽度。
QSize对象可以流式传输,也可以进行比较。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include <QSize> // QSize 类用来形容长度和宽度 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //QSize 类用来形容长度和宽度 QSize size(10,19); //交换宽和高,并返回他们交换后的值 QSize sizeTran = size.transposed(); qDebug()<<sizeTran.width(); qDebug()<<sizeTran.height(); } MainWindow::~MainWindow() { delete ui; }
QRect类使用整数精度定义平面中的矩形。矩形通常表示为左上角和一个大小。QRect的大小(宽和高)总是等价于数学矩形,构成了它的渲染基础。 QRect可以用一组左、上、宽、高整数来构造,也可以用一个QPoint和一个QSize来构造。
QRect r1(100, 200, 11, 16);
QRect r2(QPoint(100, 200), QSize(11, 16));
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); void paintEvent(QPaintEvent *); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPoint> //坐标 #include <QDebug> #include <QLine> //直线,由两个坐标点构成 #include <QSize> // QSize 类用来形容长度和宽度 #include <QPainter> //画家类 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } void MainWindow::paintEvent(QPaintEvent *){ //创建一个坐标点A,并调用方法设置坐标点的x、y轴 QPoint pointA; pointA.setX(10); pointA.setY(20); //调用有参构造器创建一个坐标点 QPoint pointB(40,80); //无参构造器默认x、y轴为(0,0) QPoint pointC; //获取坐标点的x、y轴的值。 qDebug()<< pointA.x(); qDebug()<< pointB.y(); qDebug()<<"x=" <<pointC.x()<<"y="<<pointC.y(); //QLine() //QLine(const QPoint &p1, const QPoint &p2) //QLine(int x1, int y1, int x2, int y2) QLine line(pointC,pointA); qDebug() << "直线的中点"<<line.center().x()<<","<<line.center().y(); //QSize 类用来形容长度和宽度 QSize size(200,120); //交换宽和高,并返回他们交换后的值 QSize sizeTran = size.transposed(); qDebug()<<sizeTran.width(); qDebug()<<sizeTran.height(); QRect rect(pointA,size); //实例化画家对象 this指定的是绘图设备 QPainter painter(this); //设置画笔 QPen pen(QColor(255,0,0)); //设置画笔宽度 pen.setWidth(3); //设置画笔风格 pen.setStyle(Qt::DotLine); //让画家 使用这个笔 painter.setPen(pen); //设置画刷 QBrush brush(Qt::cyan); //设置画刷风格 brush.setStyle(Qt::Dense7Pattern); //让画家使用画刷 painter.setBrush(brush); //画矩形 painter.drawRect(rect); } MainWindow::~MainWindow() { delete ui; }
//时间 void MainWindow::dateTest(){ //获取空日期对象,没有办法直接使用,需要自己添加日期 QDate date1; date1.setDate(2022,10,12); //在日期的基础上增加12天 QDate date3 = date1.addDays(12); //通过有参构造器获取日期对象 QDate date2(2022,10,10); //通过方法获取当前日期对象 QDate nowDate = QDate::currentDate(); //日期格式化输出 QString dateStr = nowDate.toString("yyyy-M-dd"); qDebug()<< date1; qDebug()<< date3; qDebug()<< date2; qDebug()<< nowDate; qDebug()<< dateStr; //获取时间对象,h must be in the range 0 to 23, m and s must be in the range 0 to 59, and ms must be in the range 0 to 999. QTime time(12,22,22,999); //获取当前时间 QTime nowTime = QTime::currentTime(); qDebug()<<time; qDebug()<<nowTime; //格式化输出 qDebug()<<nowTime.toString("hh:mm:ss"); //获取日期+时间 QDateTime dateTime(QDate::currentDate(),QTime::currentTime()); qDebug()<<dateTime; //格式化输出 qDebug()<<dateTime.toString("yyyy-MM-dd hh:mm:ss"); //获取时间戳,单位毫秒 qDebug()<< QDateTime::currentMSecsSinceEpoch(); //获取时间戳,单位秒 qDebug()<< QDateTime::currentSecsSinceEpoch(); }
信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式 (发布 - 订阅模式)。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPushButton> #include <QTextEdit> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个按钮 QPushButton * btn = new QPushButton("get_name",this); btn->move(10,40); //一个文本输入框 QTextEdit *textName = new QTextEdit("getName",this); textName->move(10,100); //为按钮添加一个点击(鼠标点击一次就是信号)事件(点击鼠标后触发的事件就是槽),下面的是Lambda表达式 connect(btn,&QPushButton::clicked,textName,[=](){ qDebug()<<"ok"; textName->setText("lihua"); }); } MainWindow::~MainWindow() { delete ui; }
信号和槽机制其实就是发布订阅模式。
一个向子线程传递参数的例子:
#ifndef MYWORK_H #define MYWORK_H #include <QObject> #include <QThread> /** * @class mywork.h * * @brief 工作线程 * * * @author: lihua * @date: 2022-10-25 15:53 */ class MyWork : public QThread { Q_OBJECT public: explicit MyWork(QThread *parent = nullptr); signals: //信号由子线程发出,主线程接收(子线程返回执行结果给主线程) void signalWork(int result); public slots: //信号由主线程发出,子线程接收(主线程传入参数给子线程) void slotWork(int num); // QThread interface protected: void run(); private: int num = 0; }; #endif // MYWORK_H
#include "mywork.h" #include <QDebug> MyWork::MyWork(QThread *parent) : QThread(parent) { } void MyWork::slotWork(int num) { //调用槽函数 qDebug()<< "子线程的槽函数被调用"<<num; this->num = num; } /** * @brief 主线程传一个初始值num给子线程,子线程在num的基础上加100 * * @param run没有参数,num是通过槽函数获取的 * * @return run没有返回值将计算结果通过槽函数返回给主线程 */ void MyWork::run() { qDebug()<< "运行子线程<<" << QThread::currentThread(); //主线程给一个初始值num int num = this->num; int result = num +100; //发出信号,订阅了此信号的订阅者的槽函数会被回调,将计算结果通过槽函数返回给主线程 qDebug()<< "结果:"<<result; emit signalWork(result); }
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include "mywork.h" #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; //子线程 MyWork *thread; // 计算结果 int result; signals: //信号 void signalMain(int num); public slots: //槽函数 void slotMain(int result); }; #endif // MAINWINDOW_H
#include "mainwindow.h" #include "mywork.h" #include "ui_mainwindow.h" #include <QThread> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); qDebug()<< QThread::currentThread(); thread = new MyWork(); //订阅signalMain信号,并指定回调函数。 connect(this,&MainWindow::signalMain,thread,&MyWork::slotWork); //订阅signalWork信号,并指定回调函数 //connect(thread,&MyWork::signalWork,this,&MainWindow::slotMain); 也可以用lamda实现 connect(thread,&MyWork::signalWork,this,[=](int result){ this->result = result; qDebug()<< "result="<<this->result; }); //发出一个信号,将10通过槽函数slotWork传递给run emit signalMain(10); thread->start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::slotMain(int result) { this->result = result; qDebug()<< "result="<<this->result; }
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPushButton> #include <QTextEdit> #include <QDebug> #include <QTimeEdit> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个按钮 QPushButton * btn = new QPushButton("get_name",this); btn->move(10,40); //一个文本输入框 QTextEdit *textName = new QTextEdit("getName",this); textName->move(10,100); //在mainwindow.ui文件创建一个时间编辑器。 QTimeEdit *timeEdit = new QTimeEdit(this); timeEdit->move(10,200); //创建一个设置时间的按钮 QPushButton *updateTime = new QPushButton("设置时间",this); updateTime->move(150,200); //为按钮添加一个点击(鼠标点击一次就是信号)事件(点击鼠标后触发的事件就是槽),下面的是Lambda表达式 connect(btn,&QPushButton::clicked,textName,[=](){ textName->setText("lihua"); }); //为时间编辑器创建一个事件 connect(updateTime,&QPushButton::clicked,[=](){ //设置为当前时间 timeEdit->setTime(QTime::currentTime()); }); } MainWindow::~MainWindow() { delete ui; }
QObject *obj = new MyWidget;
QWidget *widget = qobject_cast<QWidget *>(obj);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。