QT初识(2)

news2024/11/24 5:54:11

QT初识(2)

  • 创建好项目之后,多了些什么东西?
    • main.cpp
    • widget.h
    • widget.cpp
    • widget.ui
    • .pro项目工程文件

我们今天来继续了解QT。如果没看过上一次QT初识的小伙伴可以点击这里:

https://blog.csdn.net/qq_67693066/article/details/137194408

创建好项目之后,多了些什么东西?

创建好的项目会多出这么几个文件:
在这里插入图片描述
我们先从main.cpp程序的入口开始看:

main.cpp

main.cpp中的代码还是比较简单的:

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

这段C++代码是使用Qt库开发GUI应用程序的标准入口点代码,它创建并运行一个基于QWidget的简单桌面应用程序。下面是逐行解释:

#include "widget.h"
  • 这一行包含了名为widget.h的头文件,通常这是用户自定义的窗口类声明的地方。在Qt应用程序中,Widget通常是指继承自QWidget类的自定义窗口类,它定义了应用程序主窗口的界面布局和功能。
#include <QApplication>
  • 这行代码包含了QApplication类的头文件,这是所有Qt GUI应用程序的基础类,负责管理应用程序的事件循环、应用程序的生命周期以及窗口部件间的消息传递。
int main(int argc, char *argv[])
{
  • 这是C++程序的主入口函数,接受两个参数:argc(命令行参数的计数)和argv(指向命令行参数数组的指针)。
    QApplication a(argc, argv);
  • 创建一个QApplication对象实例a,传入argcargv参数,这样Qt应用程序就可以处理命令行参数,并且能够正确初始化事件循环和应用程序环境。
    Widget w;
  • 创建一个Widget类的对象w,这个对象将是应用程序的主窗口或用户界面。

注意一下,这个Widget类的对象是我们创建项目时勾选的,所以就生成了Widget类这么一个对象。同时要注意Widget的父类是QWidget。

    w.show();
  • 调用Widget对象wshow()函数,使窗口可见,也就是在屏幕上显示应用程序窗口。
    return a.exec();
  • 调用QApplication对象aexec()方法,开始执行Qt应用程序的事件循环。在此期间,程序会监听用户的输入、处理窗口消息和其他事件,直到退出事件(如关闭主窗口、接收到退出命令等)发生。exec()函数返回一个整数值,通常用来表示应用程序的退出状态。

总结起来,这段代码的主要作用是初始化Qt应用程序,创建并显示一个Widget窗口,并开始处理用户交互和系统事件,直至应用程序结束。

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

最重要的一部分在于如何理解和使用这个Widget类,它是继承自QWidget并结合Qt的元对象系统的GUI组件的基础结构:

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};

1. 继承自QWidget

Widget类作为用户界面的主要容器,通过继承自QWidget获得了显示窗口以及容纳各种Qt GUI控件的能力。QWidget是所有可显示窗口部件的基础类,它提供了基本的窗口管理、事件处理、布局管理以及绘图环境等功能。

2. Q_OBJECT宏

Q_OBJECT宏在这个类的声明中是非常关键的,它让Widget类能够利用Qt的元对象系统。元对象系统提供了诸如信号和槽机制(用于对象之间的异步通信)、属性系统(用于动态改变对象状态)以及国际化支持等功能。没有Q_OBJECT宏,这些特性将不可用。

3. 构造函数和析构函数

  • Widget(QWidget *parent = nullptr);
    这个构造函数初始化一个Widget对象,可以指定一个父窗口部件。如果指定了父窗口,则该Widget将成为父窗口的孩子,这会影响它的行为,比如当父窗口关闭时,子窗口也会自动关闭;另外,在布局管理上,子窗口的大小和位置通常由父窗口决定。
  • ~Widget();
    这是析构函数,当Widget对象生命周期结束时,系统会自动调用它来释放资源。在此处可能需要手动清理或者删除Ui::Widget对象,但通常情况下,如果Ui::Widget是在Widget类的构造函数中正确初始化的(例如通过setupUi()方法),那么在Widget析构时,Ui::Widget也会随之释放。

4. 成员变量Ui::Widget *ui

  • private: Ui::Widget *ui;
    这个私有成员变量指向一个Ui::Widget类型的对象,它是用户界面的具体实现。在实际的.cpp文件中,通常会有类似这样的代码:
Widget::Widget(QWidget *parent)
    : QWidget(parent),
      ui(new Ui::Widget)
{
    ui->setupUi(this); // 初始化用户界面
}

这里通过构造函数初始化ui,并调用setupUi()来加载UI文件(由Qt Designer设计并转换成代码的用户界面布局)。这样,ui对象就包含了所有界面上的控件及其布局信息,程序员可以通过ui成员变量访问和操作这些控件。

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

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


让我们聚焦于关键点:

  1. 构造函数

    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
    }
    
    • 关键点: 构造函数初始化了一个继承自QWidget的新Widget对象,同时创建了一个新的Ui::Widget实例。
    • 设计用户界面: Ui::Widget是由Qt Designer工具自动生成的,它包含了界面上所有控件的布局和属性信息。
    • 设置界面: ui->setupUi(this)是核心步骤,它将预设计的界面布局和控件绑定到当前Widget对象上,实现了图形界面的实际构建。
  2. 析构函数

    Widget::~Widget()
    {
        delete ui;
    }
    
    • 关键点: 析构函数在Widget对象生命周期结束时清理资源。
    • 内存管理: 使用delete ui;来释放之前在构造函数中动态分配给成员变量ui的内存空间,遵循C++中“谁创建谁释放”的原则,防止内存泄漏。

同时注意一下:ui->setupUi(this);这一行代码与.ui文件(如widget.ui)有直接且密切的关系。
在这里插入图片描述

在Qt开发环境中,通常会使用Qt Designer工具来设计应用程序的图形用户界面(GUI)。这个工具生成的界面布局被保存在一个.ui文件中,该文件包含了窗口、按钮、标签等各种控件以及它们之间的关系、布局等信息。
当我们在C++代码中通过Ui::Widget类(通常由Qt uic工具从.ui文件自动生成对应的ui_widget.h头文件)创建一个对象,并调用其setupUi()成员函数时,实际上是将.ui文件中定义的界面布局加载到当前的QWidget子类实例(在这个例子中是Widget类的对象)上。
所以,ui->setupUi(this);的作用就是根据.ui文件中的设计将用户界面的所有元素和布局配置应用到this所指的那个Widget实例中,实现图形界面的设计与实际C++逻辑的连接。

widget.ui

双击这个文件,我们就会进入一个图形化的编辑器,就是我们之前讲的QT Desinger:
在这里插入图片描述在这里插入图片描述
如果我们点击一下左侧栏的编辑选项,就会看到这个ui文件本来的原貌:
在这里插入图片描述

.pro项目工程文件

我们还要看一下左上方的以.pro结尾的项目工程文件:
在这里插入图片描述

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

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

它是Qt Creator IDE用于构建项目时的项目配置文件。.pro文件用于指定项目所需的模块、编译选项、源文件、头文件、UI文件以及其他构建相关的信息。以下是逐行解释:

  • QT += core gui: 指定该项目需要用到Qt的核心库(core)和图形用户界面库(gui)。
  • greaterThan(QT_MAJOR_VERSION, 4): QT += widgets: 如果Qt版本大于4,则添加widgets模块。这是因为Qt5开始引入了新的Widgets模块,而在Qt4中,widgets功能包含在gui模块中。
  • CONFIG += c++11: 启用C++11标准编译器特性支持。
  • DEFINES += QT_DEPRECATED_WARNINGS: 定义宏以便在使用Qt已弃用的API时产生编译警告。
  • 下面注释部分提到,可以进一步定义QT_DISABLE_DEPRECATED_BEFORE来阻止使用特定Qt版本之前弃用的API编译通过。
  • SOURCES += main.cpp widget.cpp: 指定项目中的源代码文件,这里包括主程序入口main.cpp和自定义Widget类的实现widget.cpp
  • HEADERS += widget.h: 指定项目中的头文件,这里包含自定义Widget类的声明widget.h
  • FORMS += widget.ui: 指定项目中使用Qt Designer设计的UI文件,这里是widget.ui,它会被uic工具转换成C++代码并整合进项目。

这些其实都是在我们创建项目时,QT自动帮我们创建好的。一般来说,初学者一般都是不用改这些文件的。

还有就是如果我们运行了一次程序,会自动出现一个文件:
在这里插入图片描述这个就是qmake的build(有点像cmake),里面的文件都有这些:
在这里插入图片描述这些都是qmake帮我们构建好的,其实跟cmake的效果差不多。

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

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

相关文章

ADB(Android Debug Bridge)操作命令详解及示例

ADB&#xff08;Android Debug Bridge&#xff09;是一个强大的命令行工具&#xff0c;它是Android SDK的一部分&#xff0c;主要用于Android设备&#xff08;包括真实手机和平板电脑以及模拟器&#xff09;的调试、系统控制和应用程序部署。 下面是一些ADB的常用命令&#xff…

全国植被覆盖度VFC逐月数据/NDVI/净初级生产力NPP/植被类型​

引言 植被覆盖度是指植被&#xff08;包括叶、茎、枝&#xff09;在地面的垂直投影面积占统计区总面积的百分比。是刻画地表植被覆盖的一个重要参数, 也是指示生态环境变化的重要指标之一。 正文 数据简介 容易与植被覆盖度混淆的概念是植被盖度&#xff0c;植被盖度是指植被冠…

腾讯云轻量服务器8核16G服务器价格1668元一年送3个月,18M大带宽

腾讯云轻量应用服务器8核16G配置租用优惠价格1668元15个月&#xff0c;买一年送3个月&#xff0c;配置为&#xff1a;轻量8核16G18M、270GB SSD盘、3500GB月流量、18M带宽&#xff0c;腾讯云优惠活动 yunfuwuqiba.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云8核16G服务器…

复写零->C语言和JAVA版本的双指针解法

使用C语言和JAVA语言版本双指针来解决复写零问题 力扣链接:https://leetcode.cn/problems/duplicate-zeros/description/ 题意:对一个数组进行复写,遇到0写两遍,非0写一遍,复写结果不能超过原数组长度,即当复写结果达到数组长度时,后面的结果数组元素直接舍弃. 例子 思路:找到…

Spring Boot单元测试全指南:使用Mockito和AssertJ

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

机器学习每周挑战——旅游景点数据分析

数据的截图&#xff0c;数据的说明&#xff1a; # 字段 数据类型 # 城市 string # 名称 string # 星级 string # 评分 float # 价格 float # 销量 int # 省/市/区 string # 坐标 string # 简介 string # 是否免费 bool # 具体地址 string拿到数据…

SAP 学习笔记 - 系统移行业务 - Migration cockpit工具 - 移行Material(品目)

本章开始&#xff0c;来研究研究移行工具 Migration cockpit。 理论啥的先放一边&#xff0c;来先做一个简单的实例&#xff0c;以对 Migration cockpit 有个大概的印象。 这里就先做一个移行品目的例子。 1&#xff0c;LTMC 启动Migration cockpit工具 默认给我启动了 IE &a…

Python基础之pandas:Series和DataFrame定义及使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Series特点二、Series使用步骤1.Series定义2.索引和切片3.series的.get()4.掩码提取5.Series运算符和广播方法6.ufunc在Series对象中使用 三、DataFrame1.D…

使用python实现i茅台自动预约

使用python实现i茅台自动预约[仅限于学习&#xff0c;不可商用] 运行&#xff1a; 直接运行 imtApi.py 打包&#xff1a;切换到imt脚本目录&#xff0c;执行打包命令&#xff1a; pyinstaller --onefile imtApi.py这个应用程序可以帮助你进行茅台自动化配置。以下是一些使用…

【Laravel】06 数据库迁移工具migration

【Laravel】06 数据库迁移工具migration 1.migration文件目录2. 举例 1.migration文件目录 2. 举例 (base) ➜ example-app php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_crea…

Java基础学习: JDK动态代理

文章目录 一、什么是JDK动态代理二、JDK动态代理的特点三、JDK动态代理类如何使用四、JDK动态代理原理分析1、创建代理对象2、生成代理类 一、什么是JDK动态代理 JDK动态代理是Java提供的一种动态生成代理类和代理对象的技术。它主要利用Java的反射机制实现&#xff0c;在运行…

算法学习——LeetCode力扣动态规划篇10(583. 两个字符串的删除操作、72. 编辑距离、647. 回文子串、516. 最长回文子序列)

算法学习——LeetCode力扣动态规划篇10 583. 两个字符串的删除操作 583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09; 描述 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个…

2010-2021年各省碳排放测算数据(含原始数据+计算过程+结果)

2010-2021年各省碳排放测算数据&#xff08;含原始数据计算过程结果&#xff09; 1、时间&#xff1a;2010-2021年 2、指标&#xff1a;原煤(万吨)、原煤(万吨CO2)、焦炭(万吨)、焦炭(万吨CO2)、汽油(万吨)、汽油(万吨CO2)、煤油(万吨)、煤油(万吨CO2)、柴油(万吨)、柴油(万吨…

vivado XVC 服务器实现

XVC 服务器实现 您需要实现 XVC 协议才能在相应的处理器上创建 XVC 服务器。 XVC 协议 XVC 协议允许 Vivado IDE 通过以太网向嵌入式系统发送 JTAG 命令 &#xff0c; 以便对目标赛灵思器件进行编程和 / 或调试。这样 即可采用任意供应商解决方案来对赛灵思器件进行调…

《Java面试自救指南》(专题一)操作系统

文章目录 力推操作系统的三门神课操作系统的作用和功能线程、进程和协程的区别并行与并发的区别什么是文件描述符操作系统内核态和用户态的区别用户态切换到内核态的方式大内核和微内核的区别用户级线程和内核级线程的区别线程的七态模型进程调度算法有哪些进程间通信的七种方式…

Python之Opencv进阶教程(2):统计图片灰度级别的像素数量

1、什么是灰度像素数量 在OpenCV中&#xff0c;可以使用**cv2.calcHist()**函数来计算图像的直方图。直方图是一种图形统计表&#xff0c;用于表示图像中每个灰度级别&#xff08;或颜色通道&#xff09;的像素数量或密度分布。以下是一个示例代码&#xff0c;演示了如何使用O…

Qt源程序编译及错误问题解决

Error 5 while parsing C:/qt-everywhere-src-6.6.2/qt-build/qtdeclarative/src/qmlmodels/meta_types/qt6qmlmodels_release_metatypes.json: illegal value .json 文件为空文件0字节&#xff0c;加 “[]”&#xff0c;不要引号。可以解决这类错误。 Qt编译 Qt for Windows…

重读Java设计模式: 深入探讨建造者模式,构建复杂对象的优雅解决方案

引言 在软件开发中&#xff0c;有时需要构建具有复杂结构的对象&#xff0c;如果直接使用构造函数或者 setter 方法逐个设置对象的属性&#xff0c;会导致代码变得冗长、难以维护&#xff0c;并且容易出错。为了解决这个问题&#xff0c;我们可以使用建造者模式。 一、建造者…

CCF2025上海国际日用百货(春季)博览会

CCF2025上海国际日用百货&#xff08;春季&#xff09;博览会 时间&#xff1a;2025年3月7-9日 地点&#xff1a;上海新国际博览中心 预订以上展会详询陆先生 I38&#xff08;前三位&#xff09; I82I&#xff08;中间四位&#xff09; 9I72&#xff08;后面四位&#xf…

算法系列--动态规划--背包问题(1)--01背包介绍

&#x1f495;"趁着年轻,做一些比较cool的事情"&#x1f495; 作者&#xff1a;Lvzi 文章主要内容&#xff1a;算法系列–动态规划–背包问题(1)–01背包介绍 大家好,今天为大家带来的是算法系列--动态规划--背包问题(1)--01背包介绍 一.什么是背包问题 背包问题是…