QT -- 初识

目录

Qt hello world 程序

想要实现hello world有两种方式,一种是纯代码方式实现,通过编写代码在显示界面上创建控件来显示hello world,另一种方式是通过直接创建控件

使用"标签"实现

在QT designer的右上角我们看到,通过树形结构,显示了当前页面有哪些空间。

快捷键Ctrl+R,运行程序。

这里可以修改文本内容。

纯代码方式实现

在widget.cpp文件中Widget类对象的构造函数中创建QLabel对象,也可以实现hello world。

c 复制代码
#include "widget.h"
#include "ui_widget.h"
#include "QLabel"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //这里是在堆上创建
    QLabel* label = new QLabel(this);
    label->setText("hello world");
}

直接运行,就可以看到结果。

注意

  • 使用QLabel的时候需要包含头文件 <QLabel>,这里QLabel可以写成<QLabel.h>,两者的写法不同可以参照C++中的头文件包含情况。
  • 这里不能直接在栈上创建,构造函数只会被运行一次,构造函数运行结束,栈被销毁,对象也会被销毁,运行起来时就看不到创建出的标签对象了。
  • 在创建QLabel对象时,需要传入this指针,给当前对象指定一个"父对象 ",这也是后面需要讲解的对象树
c 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QLabel label(this);//栈上创建,构造函数完成后,QLabel对象会被销毁
    label.setText("hello world");
}
//所以说这种方式是不推荐的

看到这里可能会想,在堆上申请资源,需要我们自己手动释放,如果内有释放资源,岂不是造成资源泄露了吗?

内存泄漏

这里不会内存泄漏的,有了对象树,对象树会帮我们管理资源的。
Qt的对象树是一种自动内存管理机制,通过父子关系将QObject及其子类对象组织成树状结构。当父对象被销毁时,会自动销毁其所有子对象。

对象树的主要功能

  • 解决内存管理问题:C++没有自动垃圾回收,手动管理内存容易出错(内存泄漏或重复删除),对象树提供了一种自动化的内存管理方式
  • 简化代码
  • 便于对象查找和遍历

有了对象树的管理,就能在合适的时机(窗口关闭/销毁),对资源进行统一的释放,这也是对象树的主要目的。如果在栈上创建对象,就会导致有一些控件提前释放,在界面上就看不见了。

验证自动化内存管理

我们可以自己对QLabel类进行封装,通过终端来打印对象的析构情况。

首先,先创建文件来对QLabel对象做封装。


完成之后,就会出现myqlabel.h和myqlabel.cpp两个文件。我们需要自己来写MyQLabel类的构造函数和析构函数。

c 复制代码
//myqlabel.h
#ifndef MYQLABEL_H
#define MYQLABEL_H
#include<QLabel>  //需要自己手动写头文件

class MyQLabel : public QLabel
{
public:
    MyQLabel(QWidget* parent);  //构造函数
    ~MyQLabel();   //析构函数
};
c 复制代码
#include"myqlabel.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    MyQLabel* label = new MyQLabel(this);
    label->setText("hello world");
}

运行结果

当关闭窗口时,终端会打印日志信息

这里出现了乱码,证明我们这里的编码方式出现了问题。但是确实是对象树会帮我们统一进行管理对象,不需要我们自己手动的去释放资源。

字符编码问题

出现了乱码问题,大多数情况下都是编码方式出现了问题。常用的两种编码方式是GBK和utf8,myqlabel.cpp源文件使用的是utf8,如何验证呢?

可以看到,果然是utf8编码格式的,如果显示的是ANSI,那就是GBK编码方式,那就能说明终端一定不是utf8的字符编码格式,所以才会出现乱码。

那我们该如何解决乱码问题呢?是修改源文件的编码方式吗?这样好像不大好,那是修改终端吗?其实也不好,这里有两种解决方式,使用QString,可以帮我们自动处理编码方式。不止是QString,QT也提供了专门用来打印日志的工具,可以自动处理编码方式。

c 复制代码
//需要包含头文件#include<QDebug>
MyQLabel::~MyQLabel()
{
    //std::cout<<"myQlabel 析构"<<std::endl;
    qDebug()<<"myQlabel 析构";
}
//qDebug是一个宏,封装了QDebug对象,可以当作cout来使用

qDebug日志打印

后续在QT中,如果想通过打印日志的方式,输出一些调试信息,都优先使用qDebug,虽然cout也行,但是cout对于编码的处理方式不大好,在windows上容易出现乱码的问题(如果是Linux使用QT Creator,一般就没事了,Linux默认的编码一般都是utf8)。

使用qDebug还有一个好处就是方便统一关闭打印调试日志,可以通过编译开关,来实现一键式关闭。

相关推荐
wjs20242 小时前
Memcached flush_all 命令详解
开发语言
zbhbbedp282793cl3 小时前
unique_ptr和shared_ptr有何区别?
java·开发语言·jvm
.NET修仙日记3 小时前
第四章:C# 面向对象编程详解:从类与对象到完整项目实践
开发语言·c#·.net·源码·教程·.net core
m0_738120723 小时前
内网横向靶场——记录一次横向渗透(三)
开发语言·网络·安全·web安全·网络安全·php
songroom3 小时前
Rust: 量化策略回测与简易线程池构建、子线程执行观测
开发语言·后端·rust
jz_ddk3 小时前
[数学基础] 瑞利分布:数学原理、物理意义及Python实验
开发语言·python·数学·概率论·信号分析
大G的笔记本3 小时前
Java JVM 篇常见面试题
java·开发语言·jvm
ZHE|张恒3 小时前
深入理解 Java 双亲委派机制:JVM 类加载体系全解析
java·开发语言·jvm