【QT】QT入门

个人主页~


QT入门

一、简述QT

1、什么是QT

QT是一个跨平台的C++开发框架,主要用于开发图形用户界面应用程序,但同样支持开发不带界面的命令行程序

这里的图形用户界面是一种人与计算机通信的界面显示格式,允许用户通过图形化的操作元素 (如窗口、图标、按钮、菜单等)与计算机进行交互而无需编写程序代码,图形用户界面的主要目的是使得用户能够更加直观、便捷地操作计算机,提高用户体验,也就是专门提供给非程序员的用户使用,因为并不是所有的用户都会编写代码

2、QT的优势

跨平台性:广泛支持几乎所有主流的操作系统

简单易用性:接口简单,容易上手

高效性:代码执行效率高,可维护性和扩展性好

发展性:有庞大的开源社区,市场份额在上升

它在一定程度上简化了内存回收的机制,并且可以进行嵌入式开发

3、应用场景

QT广泛应用于桌面应用程序移动应用程序嵌入式系统

我们熟知的WPS office 就是QT开发的

二、QT的基本使用

前面安装啥的就不再多说了

1、新建项目

(1)选择项目模版

新建项目对话框里一共有五类模版

项目模版 说明
Application QT应用程序,包括普通窗体程序和QtQuick程序
Library 可以创建动态库、静态库以及QtQuick扩展插件、QtCreator自身插件
其他项目 可以创建单元测试项目、Qt4设计师自定义控件、子目录项目等
Non-Qt-Project 非QT项目,可以创建纯C/C++项目
Import Project 导入项目,从版本控制管理系统的软件项目导入旧的项目

这里我们常用的只有第一种,然后右边会出现四类子模版

Qt Widgets Application:普通窗体模板,传统基于部件的窗体界面程序

Qt Console Application:Qt 控制台应用程序,因为 Qt 主要用于图形界面设计,这个控制台项目模板基本不用

Qt for Python:在Python下用 LGPL 的许可来开发闭源 Qt 软件

Qt Quick Application: Qt 提供的⼀种高级用户界面技术,使用它可以方便快速的为移动以及嵌入式设备开发流畅美观的用户界面,Qt Quick 模块是开发 QML 应用的标准库,提供了使用 QML 创建用户界面所需的一切,包括可视化、交互、动画、模型、视图、粒子效果以及着色效果等

(2)选择项目路径

就是选择文件保存的位置,注意这个位置一定要全英文

(3)选择构建系统


qmake:是一个构建工具,用于自动生成makefile文件,支持跨平台构建,qmake编辑的是一个后缀为.pro的文件

CMake:是一个跨平台的构建工具,本身不是一个编译器,而是一个能够生成让编译器读懂编译流程的文件工具

Qbs:已经被Qt官方弃用了,不再维护,所以没必要多说了

(4)填写类信息设置界面

上面的红框是基类的选择,目前有三种基类

基类 说明
QMainWindow 主窗口类,一般用于较为复杂的应用程序,除了中央客户区界面,还包括菜单栏、工具栏、状态栏、以及多个可停靠的工具对话框等
QWidget 最简单最基本的窗体程序,里面可以放置多个控件实现程序功能
QDialog 基于对话框的程序,对话框一般用于弹窗,也可以用于主界面显示,对话框是从QWidget继承而来的,并丰富了一些功能,如模态显示和返回值等

它们的关系就是:QWidget是QMainWindow和QDialog的父类

(5)选择语言和翻译软件

这个用不到,当我们的水平走向国际化了,就可以用了

(6)选择QT套件

把安装包的所有东西都下上,直接都选上就行了

(7)选择版本控制系统

蓝框就是如果有GIT仓库(gitee或者github)就可以选择直接传到仓库中,如果没有或者不想传就选择None

红框中是自动生成的文件

(8)创建完毕

其实QT程序的编写窗口是很明了的,感觉跟VS的布局也差不了多少

二、QT的Hello World

既然我们会创建文件了,那么我们就应该动手写第一个QT程序了,和C语言一样,这里我们来写一个Hello World程序

1、使用按钮实现

(1)纯代码方式实现

cpp 复制代码
#include "widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QPushButton* button = new QPushButton;
    button->setText("Hello World");
    button->setParent(this);
}

Widget::~Widget()
{
}

先包含按钮的头文件,然后构建一个指针,对指针进行操作,setText是设置文本,setParent是将按钮挂载到对象树上,对象树也是一种树形结构,通过对象树我们可以对树上的对象进行统一的析构,挂载在对象树上的内容才能被窗口显示

按钮默认在窗口左上角

(2)可视化操作实现

双击打开widget.ui文件,将Push Button拖到界面上,双击更改内容

这就是QT编译器自动生成的代码,我们通过自己编写的纯代码方式实现也会被解析成类似的代码

2、使用标签实现

跟上面差不多,不多说了

(1)纯代码方式实现

cpp 复制代码
#include "widget.h"
#include <QLabel>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QLabel* q = new QLabel;
    q->setText("Hello World");
    q->setParent(this);
}

Widget::~Widget()
{
}

(2)可视化操作实现

三、对象树

在QT中创建很多对象的时候会提供一个Parent对象指针,QObject是以对象树的形式组织起来的,,当创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是parent,也就是父类指针

在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children列表

当父对象析构的时候,这个列表中的所有对象也会被析构(不是继承意义上的父对象,而是树意义上的父对象)

QWidget是能够在屏幕上显示的一切组件的父类

QWidget继承自QObject,因此也集成了这种对象树关系,一个孩子自动地成为父组件的一个子组件

当我们删除子对象时,包括它的子对象们会自动从其父对象列表中删除

QT引入对象树的概念在一定程度上解决了内存问题

当一个QObject对象在堆上创建的时候,QT会同时为其创建一个对象树,不过对象树种对象的顺序是没有定义的,任何QObject对象delete的时候,如果这个对象有parent则自动将其从parent的children列表中删除,如果有孩子,则自动delete每一个孩子,可以保证没有QObject会被delete两次

QObject要在堆上创建 ,且不说栈上的空间小,局部对象的析构顺序是按照其创建顺序的相反过程,但如果子对象先创建,父对象后创建呢,先析构父对象再析构子对象会造成两次析构函数

并且在构造的时候就要指定parent对象

验证

在Hello World处右键选择AddNew,选择C++文件,在蓝框中输入自定义类名以及该自定义类的父类是哪个类,红框是自动勾选的,不用动,下面黑框的一般也不用动,上面是自己修改的类所包含的头文件,中间是自己创建的类的源文件,可以修改最底下的路径

然后点下一步然后点完成就行,手动创建的类会自动添加到目标工程中,然后将自定义的类完善修改一下

mypushbutton.h

cpp 复制代码
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

//#include <QWidget>
#include <QPushButton>
class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyPushButton(QWidget *parent = nullptr);

    ~MyPushButton();

signals:

public slots:
};

#endif // MYPUSHBUTTON_H

mypushbutton.cpp

cpp 复制代码
#include "mypushbutton.h"
#include <QDebug>
MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{
    qDebug() << "按钮构造函数调用";
}

MyPushButton::~MyPushButton()
{
    qDebug() << "按钮析构函数被调用";
}

widget.cpp

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include "mypushbutton.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    MyPushButton* b = new MyPushButton;
    b->setText("我的按钮");
    b->setParent(this);
}

Widget::~Widget()
{
    qDebug() << "Widget析构函数调用";
}

这里使用qDebug的原因是cout打印是GBK,而控制台是按照UTF-8来解析的,正好qDebug也是按照UTF-8来解析的,所以我们就用qDebug了


执行结果反映出对象树确保先释放子节点内存,后释放父节点内存

而析构函数的调用顺序则不一定遵守上述要求,因此看到子节点的析构执行在父节点之后(不能简单的认为调用析构函数就是释放内存

你想想这样如果是放在栈上那不直接炸肛了吗

四、QT窗口坐标体系

左上角为原点,往右为x轴,往下为y轴

对于嵌套窗口来说,这个坐标是对于父窗口的,也就是父窗口的左上角是原点

通过move函数可以移动控件


今日分享就到这里了~

相关推荐
薄荷故人_几秒前
从零开始的C++之旅——红黑树及其实现
数据结构·c++
m0_74824002几秒前
Chromium 中chrome.webRequest扩展接口定义c++
网络·c++·chrome
biter00882 分钟前
opencv(15) OpenCV背景减除器(Background Subtractors)学习
人工智能·opencv·学习
qq_433554548 分钟前
C++ 面向对象编程:+号运算符重载,左移运算符重载
开发语言·c++
努力学习编程的伍大侠12 分钟前
基础排序算法
数据结构·c++·算法
车轮滚滚__12 分钟前
uniapp对接unipush 1.0 ios/android
笔记
Mr.131 小时前
数据库的三范式是什么?
数据库
yuyanjingtao1 小时前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑1 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习