当前位置: 首页 > news >正文

【Qt】6.Qt对象树

文章目录

  • 1.自定义析构函数验证对象树
  • 2. 字符编码问题
  • 3. 使用输入框实现helloworld
  • 4. 使用按钮实现helloworld
  • 5. 使用纯代码方式实现按钮helloworld


1.自定义析构函数验证对象树

创建文件:mylabel.cpp

1d1e8f0f72ba5ecab856e9422cdcaeb6

cd9d98d4ee5dd649e7f1ce75b4ebc2f9

点击下一步,下一步。

可以看出Qt没有把头文件主动包含,我们要手动来添加。

40d01318d2efa5c7d56519d501349575

在Qt Creator中,可以通过F4切换头文件和对应的.cpp文件。

创建自定义的类,最主要的目的,是自定义一个析构函数,在析构函数中,完成打印,方便咱们看到最终的自动销毁对象的效果。

我们可以光标放到~Mylabel();上,然后点击alt+enter,双击在mylabel.cpp添加定义,就会自定义跳转到cpp文件并生成对应基本的析构函数。

ec2bacd45c44495c051de0b7ca30e77a

mylable.h

#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>class Mylabel : public QLabel
{
public://构造函数使用带QWidget*版本的,这样才能确保咱们自己的对象能加到对象树上Mylabel(QWidget* parent);~Mylabel();
};#endif // MYLABEL_H

mylable.cpp

#include "mylabel.h"
#include <iostream>Mylabel::Mylabel(QWidget* parent):QLabel(parent)
{}Mylabel::~Mylabel()
{std::cout <<"MyLabel 被销毁!"<< std::endl;
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "mylabel.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//使用自己定义的Mylabell代替原来的QLabel,所谓的继承本质上是扩展,保持原有功能不变的基础上,给对象扩展出一个析构函数//通过这个析构函数,打印一个自定义的日志,方便咱们观察程序运行效果Mylabel* label=new Mylabel(this);label->setText("hello world");
}Widget::~Widget()
{delete ui;
}

运行:

8ea15fcbfec4ee8278d979003f6f3c85

关闭:

ddf153920a7a611262c8ddaa563fc858

日志,有。

说明析构函数是执行了。虽然没有手动delete,但是由于把MyLabel挂到了对象树上。

此时窗口被销毁的时候,就会自动销毁对象树中的所有对象MyLabel的析构是执行到了。


2. 字符编码问题

预期打印的是“被销毁”三个中文,但是实际的显示效果,出现了乱码。

乱码问题出现的原因,有且只有一个(不局限于C++)就是编码方式不匹配。

如果你字符串本身是utf8编码的,但是终端(控制台)是按照gbk的方式来解析显示的,此时就会出现乱码。

(拿着utf8这里的数值,去查询gbk的码表),此时就会出现乱码了。

那么怎么看文件编码呢?

我们右键点击在Explorer中查看

7741ad0042e982be6cc6293f9feeab81

使用记事本打开

58675498e7702ef032670e83751dd620

记事本右下角有编码,就算没有也可以点击文件->另存为

8e9349e47940d913e1b817c2fe23fefd

当前表示中文,主流的方式,还得是utf8(支持各种语言文字)

Qt中有一个东西,QString,是可以帮助我们自动的处理编码方式的

不止是QStringQt也提供了专门用来打印日志的工具,也能自动处理编码方式

std::cout<<"MyLabel被销毁!"<<std::endl;

Qt中提供了一个qDebug()工具,借助这个,就可以完成打印日志的过程,很好的处理字符编码(不需要程序员关注了,内部帮咱们搞好了)

d9c46c7e26b1e9bfbc4f3e5369d8ab0c

运行,关闭:

8d7dbefde023324d23778df18f5850cc

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

使用qDebug,还有一个好处:打印的调试日志,是可以统一进行关闭的。

输出的日志,是开发阶段,调试程序的时候,使用的。如果你的程序发布给用户,不希望用户看到这些日志的,qDebug可以通过编译开关,来实现一键式关闭。

那我之前调试程序,都是用调试器VS/gdb,为啥要打印日志调试呢?

调试器很多时候是有局限性的,是无法使用的。

假设当前bug是一个概率性的bug,出现的概率是1%甚至更小,要想调试,无法使用调试器了。

使用日志,就可以很好的解决这种问题。

无论是哪种方式,本质上都是观察程序执行的中间过程和中间结果。


3. 使用输入框实现helloworld

3b76c7ba2367a23aa40817eeee5eb23e


4. 使用按钮实现helloworld

使用普通按钮

84e056b3565a1087d409f0592e133525

把文字替换,运行

24197998cc3dc31dca5930f44896a988

不过现在点击没有变化,想要有变化可以依赖后面的信号槽

本质就是给按钮的点击操作,关联上一个处理函数。当用户点击的时候,就会执行这个处理函数。

Linux网络编程中,也学过一个函数,叫做connect

这个函数用来给TCPsocket建立连接的,写TCP客户端的时候,就需要先建立连接,然后才能读写数据。

Qt中的connectQObject这个类提供的静态函数,作用是“连接信号和槽”。和TCP的建立连接操作没有任何关系!!

91875a05ed72957f67299951768154f8

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handleClick();private:Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(ui->pushButton,          // 信号发送者:界面上的那个按钮(谁发出了信号)&QPushButton::clicked,   // 发送的信号:按钮被“点击”这个动作(发出了什么信号)this,                    // 信号接收者:当前的Widget窗口对象(谁来处理这个信号)&Widget::handleClick);   // 接收信号后要执行的槽函数:我们自己写的handleClick函数(怎么处理这个信号)
}Widget::~Widget()
{// 释放ui指针所指向的内存// 因为在构造函数里用了 new Ui::Widget,所以这里需要手动delete来避免内存泄漏delete ui;
}void Widget::handleClick()
{//当按钮被点击之后,就把按钮中的文本进行切换if(ui->pushButton->text()==QString("hello world")){ui->pushButton->setText("hello qt");}else{ui->pushButton->setText("hello world");}}

按钮点击一次切换一次

d67c3f6d261de072b84103fae963c554

可以打开编译后生成文件夹里的.ui文件:

930a056af746656c57f5e796912864c8

ui_widget.h中自动生成的代码里就会包含一个pushButton的成员变量,这个变量的名字,就是根据objectName的值来确定的。

我们可以验证一下:

先改一下 里面的数值为mybutton

f5251bcb784d8d013b0aa387a773c798

3294ac5f7e0f170d2b9c302eb47a3dd5

此时打开之前的.ui文件

8404a3c87b1f028890b92d941dd67253


5. 使用纯代码方式实现按钮helloworld

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QPushButton>#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handleClick();private:Ui::Widget *ui;QPushButton* myButton;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);myButton = new QPushButton(this);myButton->setText("hello world");connect(myButton,&QPushButton::clicked,this,&Widget::handleClick);
}Widget::~Widget()
{delete ui;
}void Widget::handleClick()
{if(myButton->text()==QString("hello world")){myButton->setText("hello qt");}else{myButton->setText("hello world");}
}

运行:

b5d8dbf7c38b46e44559a0bcba0b9696

和之前图像化实现的区别是:

纯代码实现:需要自己new一个myButton,而且为了保证其他函数中能够访问到这个变量,就需要把按钮对象设定为Widget类的成员变量.

图形化实现:此时按钮对象,不需要咱们自己newnew对象的操作已经是被Qt自动生成了。而且这个按钮对象,已经作为ui对象里的一个成员变量了。也无需作为Widget的成员。

实际开发中,是通过代码的方式构造界面,为主,还是通过图形化界面的方式构造界面为主??

这两种,都很主要,难分主次。

  • 如果你当前程序界面,界面内容是比较固定的,此时就会以图形化的方式来构造界面
  • 但是如果你的程序界面,经常要动态变化,此时就会以代码的方式来构造界面

这两种方式,哪种方便就用哪种,而且这两种方式也可以配合使用。

http://www.dtcms.com/a/486602.html

相关文章:

  • 使用Scanpy的基本操作
  • openssl s_client 命令——测试、调试和诊断 SSL/TLS 连接
  • 深度学习中的RNN与LSTM:原理、差异与应用
  • 湖南智能网站建设报价广西南宁网站排名优化
  • 广州网站建设十年乐云seo北京东直门网站建设
  • h5游戏免费下载:卡通飞行
  • IntelliJ IDEA 配置 Gitee 私人令牌完整指南(2025 年最新版)
  • 智尚招聘求职小程序v1.0.23
  • 网站快照历史代发新闻稿的网站
  • [数据抓取-1]beautifulsoup
  • 分形:曼德布洛特集合
  • 克拉玛依建设局网站外贸整合推广
  • 哪家网站推广好网站备案 办公室电话
  • 金蝶KIS报表系统:全场景数据可视化解决方案
  • 轻量安全、开箱即用:0 成本开启数据实时同步
  • webpack实现常用plugin
  • abap 操作 excel
  • Excel VLOOKUP函数完全教程:从基础到高级实战
  • 网站建设定制设计网站后台怎么添加代码
  • 网站推广软件预期效果专业团队原版视频
  • 个人网站首页导航栏ps制作教程培训课程ui设计
  • 2025WPF 面试高频问题及标准答案
  • 直线电机(S7-1511PN Linmot C1251)调试文档
  • Leetcode 28
  • 【完整源码+数据集+部署教程】 【零售和消费品&存货】【无人零售】自动售卖机饮料检测系统源码&数据集全套:改进yolo11-KernelWarehouse
  • iOS框架内存中占用很高的ttc文件是否正常
  • 建设部网人事考试网站企业宣传片怎么拍
  • 料神wordpress建站教程优购物官方网站直播
  • Spring Boot 3零基础教程,yml语法细节,笔记16
  • 31-基于ZigBee的车位引导系统设计与实现