QT初识

news2024/12/26 11:40:21

通过图形化界面输出helloworld

既然学习了QT,那么自然要做经典的输出helloworld字符串的实验。

QT有两好几种方案输出helloworld,一种是通过图形化界面输出,一种是通过代码实现。

这里先了解图形化界面的方案。

创建项目后,点击 .ui 文件进入到QTdesigner界面。

然后在左边的控件中,选择一个标签控件,拖拽到画布上后。

然后双击该标签,即可输入文本字符串。 

 

这样运行后的窗口就自带一个 helloworld 字符串了。

然后再点击编辑查看 .ui 文件的本体,可以发现 xml 格式中出现了一个字符串,其值是 ''helloworld''

 通过纯代码输出helloworld

首先在 mainwindow.cpp 中,找到 MainWindow 的构造函数。

然后包含头文件 QLabel,之后创建一个 QLabel 对象,并且设置字符串 'hello world' 即可。

不过这里没有设置标签的位置,因此默认在左上角。 

这里的 QLabel 对象是通过 new 得到的,但是我这里并没有通过其他函数来将该对象的内存释放

这会不会造成内存泄漏呢?实际上是不会的。

对象树

在QT中有一个新概念——对象树。

对象树是一种多叉树,树的节点都是一个个new出来的对象。

在对象 new 的时候可以指定它的 parent ,通过该 parent 指针来将对象挂在对象树上。

这样一个对象的生命周期就由对象树管理起来了。

而如果没有挂在对象树上,就需要手动释放了

在QTdesigner中可以看到对象树的结构。

这里的 label 对象就是挂在一个 QWidget 类对象下面,而这棵树就是 MainWindow。 

验证对象树是否会释放节点

首先我们需要自己定义一个新类。

在左上角点击新建文件或项目。

 选择文件和类中的 C++,并且选择C++Class

 然后设定该类的名称,最好类名和头文件的名称相同。

然后设定添加到哪个项目中,点击确定就完成了。

 这样就成功创建一个头文件和cpp文件了。

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QMainWindow>
#include <QLabel>

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    MyLabel(QWidget * parent);
    ~MyLabel();
};

#endif // MYLABEL_H

因为是需要挂在 QWidget 下的,因此需要在构造函数时将传入 QWidget 指针用以挂在对象树上。

而且这个 MyLabel 是直接继承自 QLabel 的,因此可以直接使用 QLabel 的函数。

其次 QT 有一个小技巧。

如果一个类有声明了但是没有定义的函数,可以将光标移到该函数,然后通过 alt + enter 后即可在 .cpp 文件中直接定义。 

#include "mylabel.h"
#include<iostream>
using namespace std;

MyLabel::MyLabel(QWidget * parent) : QLabel(parent)
{

}

MyLabel::~MyLabel()
{
    cout<<"MyLabel 被析构了!"<<endl;
}

定义完后我们直接定义好 .cpp 函数的实现。

 接着在 MainWindow 中使用 MyLabel 来挂在对象树上,然后运行。

可以发现成功输出了,然后关闭窗口。

即可在 应用输出窗口 中看到输出的析构函数的内容,不过有乱码。

这是因为中文具有两种不同的字符编码集,如果文件的编码集和工具的编码集不同,就会出现这种乱码问题。

虽然 Windows 上有这个问题,不过 linux 上的QT就没有问题。

这里我们可以使用QT提供的 QDebug 类来输出,它会自动处理字符编码集的转换问题。

 QDebug 的使用方式和 cout 类似,不过不需要手动换行,它会自动换行。

并且 QDebug 正如名字所说,是用于调试的工具,它输出的内容只有在 Debug 版本下才能看到,可以通过编译开关一键关闭。

通过按钮输出helloworld

图形化方式

在 QTDesigner 中还有很多其他的控件可以实现输出 helloworld 的功能。

我们可以通过图形化界面的方式来输出 hello world。

比如这样就能够直接输出,不过只是单纯的输出实在是无聊了。

那么我们设置成按下这个按钮后,按钮的文本就会改变应该如何做呢?

当我们为画布添加了一个控件时,点击这个控件可以看到它的名字,我们能够手动修改,这里按钮的名字就是 pushButton 。

而当我们在界面下用鼠标对 pushButton 按下去后,会对这个界面发送一个信号——clicked。

我们可以通过 connect 函数来将这个信号和一个函数进行连接,这样按下这个按钮后就会自动执行这个函数。

这一部分是信号与槽的内容,不过可以先了解一下。

这个信号是 ui 界面中的 pushButton 发出的发出的信号是 QPushButton 中的 clicked 信号接受信号的是 this ,也就是 MainWindow 对象来处理,其处理动作是 clickHandler,也就是用户自己设置的函数或是QT自定义的其他函数,这里是我自己设置的函数。 

这个函数的动作就是 : 如果按钮的文本是 "hello world" 就把文本替换成 "hello qt",否则替换成"hello world"。

 

可以看到成功替换了文本。

代码方式 

首先在 MainWidos.h 中设置 QPushButton 成员变量。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void clickHandle();
private:
    Ui::MainWindow *ui;
    QPushButton* myButton;
};
#endif // MAINWINDOW_H

然后在 MainWindow.cpp 中自己设置和 connect 即可。 


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    myButton = new QPushButton(this);
    myButton->setText("hello world");
    connect(myButton,&QPushButton::clicked,this,&MainWindow::clickHandle);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::clickHandle()
{
    if(myButton->text() == "hello world")
    {
        myButton->setText("hello qt");
    }
    else
    {
        myButton->setText("hello world");
    }
}

可以看到确实实现了。 

QT的坐标系

QT的坐标系并不是以左下角为(0,0)的,而是以左上角为 (0,0) 的,也就是左手坐标系。

这也是为什么我们使用代码的方式来使用控件的时候,它们的位置默认在左上角。

我们可以通过 move 函数来移动它们的位置。

我们将 myButton 按钮移动到距离 MainWindow 的 (0,0) 位置 为 (200,500) 的位置。

 

发现按钮的位置不在左上角了!

而 MainWindow 此时是 myButton 这个对象的父节点,那么 MainWindow 呢?它的父节点呢?

其实 MainWindow 的父节点就是显示器,也就是说如果我们调用 MainWindow 的 move 函数,就能修改窗口的位置!

 我们在 main.cpp 中调用 move 函数。

发现位置改变了。

而 move 函数移动的单位是什么呢?实际上就是电脑显示器的像素点。 

总结

通过本文我们了解了 QT 能够通过图形化界面简单快速的实现一个页面,也能够通过代码直接使用控件。

并且了解到 QT 开辟的内存可以通过挂在对象树的方式来控制生命周期,而不用手动释放。并且了解到一些前置的信号与槽的见到应用,以及QT的坐标系。相信对大家一定会有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1620475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高频前端面试题汇总之HTML篇

1. src和href的区别 src和href都是用来引用外部的资源&#xff0c;它们的区别如下&#xff1a; src&#xff1a; 表示对资源的引用&#xff0c;它指向的内容会嵌入到当前标签所在的位置。src会将其指向的资源下载并应⽤到⽂档内&#xff0c;如请求js脚本。当浏览器解析到该元素…

函数式接口及Stream流式计算

一、什么是函数式接口 只有一个方法的接口&#xff0c;例如 FunctionalInterface public interface Runnable { public abstract void run(); }二、Function函数式接口&#xff1a;有一个输入参数&#xff0c;有一个输出 三、断定型接口&#xff1a;有一个输入参数&#xf…

如何用虚拟仿真实训室提质增效?

为积极推进教学改革&#xff0c;优化人才培养方案&#xff0c;紧跟产业发展趋势&#xff0c;响应教育领域数字化改革要求&#xff0c;越来越多院校通过搭建虚拟仿真实训室、数字人实训室&#xff0c;打通了融“理论知识虚拟训练技能训练”为一体的教学和实训。学生通过数字人实…

代码随想录 Day19 字符串 | LC28 实现strStr() 【KMP经典题目】

六、实现strStr() 题目&#xff1a; 力扣28&#xff1a;找出字符串中第一个匹配的下标 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack…

大模型检索召回系统:RAG技术的全面调查与未来展望

随着人工智能技术的飞速发展&#xff0c;大型语言模型&#xff08;LLMs&#xff09;在自然语言处理&#xff08;NLP&#xff09;领域取得了显著成就。然而&#xff0c;这些模型在处理特定领域或知识密集型任务时仍面临挑战&#xff0c;如产生错误信息或“幻觉”。为了克服这些难…

代码随想录算法训练营33期 第五十天 | 188.买卖股票的最佳时机IV

dp[i][0] 不操作&#xff1b;d[i][1]第一次开始持有股票 //dp[i]当前天i的价值情况&#xff0c;dp[i][0]表示不操作的最大价值&#xff0c;dp[i][1]在当前天第一次持有的最大价值&#xff0c;dp[i][2]在当前天第一次卖出的最大价值, dp[i][3]在当前天第二次持有的最大价值&am…

qmt教程2----订阅单股行情,提供源代码

链接 qmt教程2----订阅单股行情&#xff0c;提供源代码 (qq.com) qmt教程1---qmt安装&#xff0c;提供下载链接 今天我重新封装了全部qmt的内容&#xff0c;包括数据&#xff0c;交易 qmt交易 我本来打算全部上次git的&#xff0c;但是考虑到毕竟是实盘的内容&#xff0c;就放…

项目总结计划-(Word)

项目总结计划书-Word 2 项目工作成果 2.1 交付给用户的产品 2.2 交付给研发中心的产品 2.2.1 代码部分 2.2.2 文档部分 2.3 需求完成情况与功能及性能符合性统计 2.3.1 需求完成情况统计 2.3.2 功能符合性分析 2.3.3 性能符合性分析 3 项目工作分析 3.1 项目计划与进度实施分…

消息队列一文全解!!!

消息队列的用途是什么&#xff1f; 第一章 消息队列的用途是什么&#xff1f; 第二章 消息重复消费如何避免&#xff1f; 第三章 消息的顺序性可靠性如何保证&#xff1f; 第四章 高可用的消息队列如何搭建&#xff1f; 第五章 消息队列面试题汇总 文章目录 消息队列的用途是什…

Vue页面生成导出PDF文件

第一种&#xff1a; 使用浏览器自带打印方法window.print(); 也可使用print-js插件&#xff08;原理相同&#xff09; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>printDemo</title> </…

安防监控/智能分析EasyCVR视频汇聚平台海康/大华/宇视摄像头国标语音GB28181语音对讲配置流程

一、背景分析 近年来&#xff0c;国内视频监控应用发展迅猛&#xff0c;系统接入规模不断扩大&#xff0c;涌现了大量平台提供商&#xff0c;平台提供商的接入协议各不相同&#xff0c;终端制造商需要给每款终端维护提供各种不同平台的软件版本&#xff0c;造成了极大的资源浪…

测试工程师面试准备(软硬件)

您好&#xff0c;我叫XXX。学历XX&#xff0c;XXX专业毕业。X年X月份毕业&#xff0c;但是去年二月份已经找到工作开始实习了&#xff0c;目前工作一年了&#xff0c;这一年的过程中我主要负责软件的开发和测试和软硬件联调测试工作。具体来说就是&#xff0c;在软件开发完成后…

制造业小企业内部小程序简单设计

也没什么需求&#xff0c;就是看企业内部外来单位就餐还需要打印客饭单拿去食堂给打饭师傅&#xff0c;出门单还需要打印纸质版&#xff0c;车间PDA扫码出问题需要人手动处理&#xff0c;会议室需要OA申请&#xff0c;但是申请前不知道哪些会议室事空的(因为不是每个人都下载OA…

neovim0.9版本安装

一 安装 Installing Neovim neovim/neovim Wiki (github.com)https://github.com/neovim/neovim/wiki/Installing-Neovim/921fe8c40c34dd1f3fb35d5b48c484db1b8ae94b 1 下载 curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage chmod ux n…

【黑马点评Redis——003优惠券秒杀4——消息队列Stream】

1. 目前还存在的问题 设置的阻塞队列可能会超出最大长度系统重启会导致阻塞队列中的信息消失&#xff0c;可能会出现问题 2. 消息队列 消息队列 (Message Queue)。 字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色消息队列:存储和管理消息&#xff0c;也被称为…

网页自动跳转到其他页面,点击浏览器返回箭头,回不到原来页面的问题

背景&#xff1a;今天产品提个需求&#xff0c;需要从index页面自动触发跳转到下一页面的事件&#xff0c;从而不做任何操作&#xff0c;直接跳转到test页面。 代码是这样的&#xff1a; index.vue: <template><div style"width:500px;height:600px;background-…

20 Debian如何配置DNS服务(2)主从服务器

作者&#xff1a;网络傅老师 特别提示&#xff1a;未经作者允许&#xff0c;不得转载任何内容。违者必究&#xff01; Debian如何配置DNS服务&#xff08;2&#xff09;主从服务器 《傅老师Debian小知识库系列之20》——原创 前言 傅老师Debian小知识库特点&#xff1a; 1、…

纸箱码垛机:从传统到智能,科技如何助力产业升级

随着科技的飞速发展&#xff0c;传统工业领域正经历着一场重要的变革。作为物流行业重要一环的纸箱码垛机&#xff0c;其从传统到智能的转型升级&#xff0c;不仅提高了生产效率&#xff0c;还大幅降低了人工成本&#xff0c;为产业升级提供了强大助力。星派将探讨纸箱码垛机的…

【一些神金】怎么缓解工作压力?使用VS-code彩虹屁插件

怎么缓解工作压力&#xff1f; 其实吃点好的&#xff0c;多睡一会儿&#xff0c;再锻炼锻炼身体就好。 但我只是想炫耀一下这个彩虹屁插件。 原版插件&#xff1a;VS-code-Rainbowfart 我的版本&#xff1a;RainbowFart-Oberon 基于 MIT 开源&#xff0c;包括所有设计资源及音…

大数据信用风险竟然是这样形成的!查询方法也很简单

在大数据时代背景下&#xff0c;大数据信用风险成为了众多机构关注的焦点。这类风险涵盖了多头借贷、履约行为、联系人以及司法等多个方面。本文将深入解析大数据信用风险的形成原因及其查询方法&#xff0c;让我们一起来探索一下。 大数据信用风险主要表现在以下几个方面&…