QT初步简介

Qt模块

模块 描述
Qt Core Qt 类库的核心,所有其他模块都依赖于此模块
Qt GUI 设计 GUI 界面的基础类,包括 OpenGL
Qt Multimedia 音频、视频、摄像头和广播功能的类
Qt Multimedia Widgets 实现多媒体功能的界面组件类
Qt Network 使网络编程更简单和轻便的类
Qt QML 用于 QML 和 JavaScript 语言的类
Qt Quick 用于构建具有定制用户界面的动态应用程序的声明框架
Qt Quick Controls 创建桌面样式用户界面,基于 Qt Quick 的用户界面控件
Qt Quick Dialogs 用于 Qt Quick 的系统对话框类型
Qt Quick Layouts 用于 Qt Quick 2 界面元素的布局项
Qt SQL 使用 SQL 用于数据库操作的类
Qt Test 用于应用程序和库进行单元测试的类
Qt Widgets 用于构建 GUI 界面的 C++ 图形组件类

内容重述

QT,hello word!,初步建立UI,代码生成UI,代码和手动UI优缺点对比,默认生成文件对比,Object Trees自动释放子类new空间,信号和槽

  • Qt的安装路径和文件命名不能有中文
  • Qt默认UFTF8编码

启动QT

启动QT桌面的应用
启动QT桌面的应用

基于对话框!Dialog

创建新项目,基于如下相关设置,QDialog基于对话框的QT

选择建立的系统
选择建立的系统使用qmake

选择class类型以及class名字
选择class类型以及class名字

选择编译组件
选择编译组件

最后的summary
最后的summary

UI编辑区

UI编辑区
UI编辑区

在编辑的pro文件下,最后添加RC_ICONS = myico.ico

此ico文件需要提前在下载并放到文件代码所在位置

添加窗口logo
添加窗口logo

运行

点击左下角的运行,可选择调试发布两种,当要发布当前文件时选择release

hello word执行窗口
hello word执行窗口

QT软件的发布

在QT文件夹下使用QT cmd窗口输入,使用windeployqt将QT运行所需要的动态库存入到myfirstQTAPP当中(注意myfirstQTAPP需要提前将QT release所生成的exe文件存入到此文件夹中)。

windeployqt E:\C++study\QT\QT_exercise\QT01\myfirstQTAPP

生成后发布的文件
生成后发布的文件

Qwidget

创建项目Base class 选择Qwidget创建的界面对所有的界面相关组件都是支持的

.pro文件详解

# 在此项目中加入core gui核心(控制台不需要)
# QT是以模块的形式组织类库,根据项目需求不同添加不同类库的支持
QT       += core gui

# 当QT版本大于4,在当前项目中添加widgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# 都为自动生成的
# 源代码
SOURCES += \
    main.cpp \
    widgets.cpp
# 头文件
HEADERS += \
    widgets.h
# ui文件
FORMS += \
    widgets.ui

# Default rules for deployment.默认部署规则
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

槽类似信号,当点击之后对相关函数进行响应。

槽

Signals and Slots Editor信号与槽编辑,

  • 发送者即点击的对象,如图点击pushButton_2上面close,
  • 第二个信号为clicked()即当点击发送者的时候,
  • 接受者为 发送者执行信号clicked()然后接受者执行
  • close()接受者widgets(窗口)即关闭窗口,
    信号与槽操作
    信号与槽操作

main.cpp

#include "widgets.h"

#include <QApplication>  //qt的标准应用程序,QT必须有得

int main(int argc, char *argv[])
{
    //应用程序对应,在一个Qt项目中实例对应有且仅有一个
    //类的作用:检测触发的事件,进行事件循环并处理
    QApplication a(argc, argv); //必须引用对应的#include <QApplication>
    //widgets创建w对象
    widgets w;
    //w调用show方法,显示窗体
    w.show();
    //a为qt的应用程序,返回让qt执行起来。
    //应用程序对应开始事件循环,保证应用程序不退出,阻塞函数
    return a.exec();
}

widgets.h

#ifndef WIDGETS_H
#define WIDGETS_H

#include <QWidget>

QT_BEGIN_NAMESPACE
//命名空间Ui里面的widgets类
namespace Ui { class widgets; }
QT_END_NAMESPACE
//此widgets与上面命名空间的ui里的widgets不同,在不同的命名空间
class widgets : public QWidget //来自Qwidget基类
{
    //宏,使用QT的信号与槽都要使用到此宏
    Q_OBJECT

public:
    //构造函数和析构函数
    widgets(QWidget *parent = nullptr);
    ~widgets();

private:
    //私有成员ui命名空间里面的widgets
    //定义指针指向窗口的UI对象
    Ui::widgets *ui;
};
#endif // WIDGETS_H

widgets.cpp

#include "widgets.h"
#include "ui_widgets.h"
#include "testwidget.h"
widgets::widgets(QWidget *parent)
    : QWidget(parent), ui(new Ui::widgets) //开辟类内存空间
{
    //调用setupUi,
        //通过此就可修改主窗口的相关设置于获取
    ui->setupUi(this); //实现窗口的各种空间属性,信号与槽关联等
    
    //一般在qt的构造函数中进行数据初始化操作(窗口,数据....)
    //如显示当前窗口,并显示另一个窗口
    //要独立显示窗口,必须要进行show操作
#if 0:
    TestWidget* w = new TestWidget;
    //显示当前窗体
    w->show();
# else
	// 指定了父对象,子窗口和父窗口一起显示出来,内嵌入父窗口
	TestWidget* w = new TestWidget(this);  //显示到this里面,testwidget被嵌入到this对应的主窗口
#endig
}

widgets::~widgets()
{
    // 析构函数释放new的空间
    delete ui;
}

使用代码实现在widgets上的功能

QMainWindow带菜单栏的窗口
使用代码实现不创建UI相关文件

文件列表
文件列表

可视化和代码编写对比:

  • 可视化用编写代码,极大的省去界面布局调节时间成本
  • 但有些组件没法完全通过ui进行可视化添加需要设计纯代码
  • 纯代码确实效率会低,繁琐,但可补充ui无法实现的功能

对象数Object Trees

QObjects organize themselves in object trees. When you create a QObject with another object as parent, it’s added to the parent’s children() list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a QShortcut (keyboard shortcut) is a child of the relevant window, so when the user closes that window, the shortcut is deleted too.
QQuickItem, the basic visual element of the Qt Quick module, inherits from QObject, but has a concept of the visual parent which differs from that of the QObject parent. An item’s visual parent may not necessarily be the same as its object parent. See Concepts - Visual Parent in Qt Quick for more details.
QWidget, the fundamental class of the Qt Widgets module, extends the parent-child relationship. A child normally also becomes a child widget, i.e. it is displayed in its parent’s coordinate system and is graphically clipped by its parent’s boundaries. For example, when the application deletes a message box after it has been closed, the message box’s buttons and label are also deleted, just as we’d want, because the buttons and label are children of the message box.
You can also delete child objects yourself, and they will remove themselves from their parents. For example, when the user removes a toolbar it may lead to the application deleting one of its QToolBar objects, in which case the tool bar’s QMainWindow parent would detect the change and reconfigure its screen space accordingly.
The debugging functions QObject::dumpObjectTree() and QObject::dumpObjectInfo() are often useful when an application looks or acts strangely.

QDebug

In the common case, it is useful to call the qDebug() function to obtain a default QDebug object to use for writing debugging information.

#include <QDebug> //引用QDebug头文件
qDebug() << "Date:" << QDate::currentDate();

在NO_UI新建一个QMyClass类

验证Object Trees关闭是否可以自动释放new的空间,而无需再析构函数手动delete申请的空间

代码验证

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include <QLabel>
#include <QPushButton>
#include "qmyclass.h" //引用刚才自己创建的类
//对象树//窗口部件的销毁也会相应销毁子部件label等内容申请的空间
//所以只需申请new而无需delete
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //让其窗口隶属于父类1,2,3
    //请求Qlabel空间
    QLabel *label = new QLabel(this); //3,直接带参数,直接隶属于其父类
    //设立text文件
    label->setText("I Love You,XinXin");
    //设置位置
    label->move(150,100);

    //c创建按钮,但并未有操作功能
    QPushButton *button = new QPushButton(this); //this内嵌到父类
    button->setText("Close"); //设置Pushbutton内的文字
    button->setFixedSize(200,200); //设置按钮的固定大小
    button->move(150,180); //起点为父类的左上角

    //当窗口被关闭后,QMyClass的析构函数也被自动调用
    //只需写new,无需再手动写含delete的内容
    QMyClass *myclass = new QMyClass(this);


    //1,此形式呈现会呈现在独立的窗口
    //label->show();

    //2,让label隶属于其父类
    //label->setParent(this);

    //指定窗体的大小
    resize(400,300);
    //锁定大小,不可改变
    //setFixedSize(400,300);

    setWindowTitle("My First No UI");

}

Widget::~Widget()
{
    //

}

qmyclass.h

#ifndef QMYCLASS_H
#define QMYCLASS_H

#include <QWidget>

class QMyClass : public QWidget
{
    Q_OBJECT
public:
    explicit QMyClass(QWidget *parent = nullptr);
    ~QMyClass(); //作为判断析构函数是否被调用到
signals:

};

#endif // QMYCLASS_H

qmyclass.cpp

#include "qmyclass.h"
#include <QDebug>  //输出内容头文件
QMyClass::QMyClass(QWidget *parent)
    : QWidget{parent}
{

}
QMyClass::~QMyClass()
{
    //QT打印内容,qDebug输出内容
    qDebug() << "delete myclass"; //当手动关系窗口,析构函数被调用
}

main.cpp和NO_UI.pro不变

基础窗口类

  • QWidget
    • 所有窗口类的基类
    • Qt 中的控件 (按钮,输入框,单选框…) 也属于窗口,基类都是 QWidget
    • 可以内嵌到其他窗口中:没有边框
    • 可以不内嵌单独显示:独立的窗口,有边框
  • QDialog
    • 对话框类
    • 不能内嵌到其他窗口中,必须调用show方法才显示。
  • QMainWindow
    • 工具栏,状态栏,菜单栏
    • 不能内嵌到其他窗口中

窗口的显示

  • 内嵌窗口
    • 依附于某一个大的窗口,作为了大窗口的一部分
    • 大窗口就是这个内嵌窗口的父窗口
    • 父窗口显示的时候, 内嵌的窗口也就被显示出来了
  • 不内嵌窗口
    • 这类窗口有边框,有标题栏
    • 需要调用函数才可以显示show
//QWidget是所有窗口类的基类,调用这个提供的show()方法显示窗口 非模态显示
void QWidget::show(); //显示当前窗口和它的子窗口
//对话框窗口的模态显示,//会阻塞当前窗口,不能切换到其它窗口
[virtual slot] int QDialog::exec();

Qt坐标

Qt的坐标原点在窗口左上角.内嵌的情况下基于其父窗口。
x轴递增,
y轴递增

Qt内存回收

new创建堆内存,
析构顺序从子窗口到顶层主窗口
若创建的对应是QObject类的之类(间接之类也可).创建的对应,必须要指定其父对象是谁,

//通过构造函数parent当前窗口的父对象
QWidget::QWidget(QWidget *parent = Q_NULLPTR,Qt::WindowFlags f = Qt::WindowFlags());
QTimer::QTimer(QObject *parent = nullptr)

//2,通过setParent()方法
void QWidget::setParent(QWidget *parent)
void QObject::setParent(QWidget *parent)

Qt log输出

#include <QDebug>
QDebug() << "输出日志";

若向将log日志文件输出到控制台,进入pro文件,在CONFIG后面加 console,重新构建即可。

CONFIG += C++11 console

字符类型

QByteArray

char* 的升级版

QString

QString是QByteArray封装
QString计算长度根据字符个数,而QByteArray是将一个中文字符对应三个
具体参考 原文

QVariant

使用QVariant自定义类型进行处理

struct Person
{
	int id;
	QString name;
}

// 引用
//创建Person对象
Person p;
p.id = 25;
p.name = "张三";
//将其设置为QVariant有两种方法
#if 0
	QVariant v;
	v.setValue(p);
#else
	QVariant v = QVariant::fromValue(p)
#endif
	//取出V对象中的数据
	if(v.canConvert<Person>())
	{
		//转换
		Person tmp = v.value<Person>();
		qDebug()<<tmp.id<<tmp.name;
	}

参考资料:
* 爱编程的大丙: 详细部分 https://subingwen.cn/qt/qt-basetype/
* 嵌入式开发设计