【QT学习】01:helloqt

news2024/12/26 11:14:25

helloqt


OVERVIEW

  • helloqt
      • 一、helloqt
        • 1.使用向导创建
        • 2.手动创建
        • 3.pro文件
        • 4.Qt应用程序框架
      • 二、按钮创建
        • main.cpp
        • mywidget.cpp
      • 三、对象模型
        • 1.对象树引入
        • 2.存在的问题

一、helloqt

创建一个qt项目,可以使用creator的向导创建,也可自己手动创建:

1.使用向导创建

  • step1:文件->新建文件或项目,选择Qt Widgets Application(创建一个qt桌面应用,包含一个基于qt设计师的主窗体)

  • step2:填写项目名称,并设置项目存放路径后,选择编译套件(例如:Desktop Qt 5.5.0 MinGW 64bit)

  • step3:向导会自动添加一个继承自CMainWindow的类,可以在此修改类的名字和基类(默认基类有QMainWindow、QWidget、QDialog)

    在这里插入图片描述

  • step4:向导会默认添加main.cpp、mywidgets.cpp、mywidgets.h和一个.pro项目文件,点击完成即可创建出一个qt桌面程序。

2.手动创建

  • step1:文件->新建文件或项目,添加一个空项目Empty qmake Project,

  • step2:填写项目名称,并设置项目存放路径后,选择编译套件(例如:Desktop Qt 5.5.0 MinGW 64bit)生成一个空项目。

  • step3:在空项目中添加文件,选择C++ Class添加即可。

    在这里插入图片描述

3.pro文件

.pro 就是工程文件,其是qmake自动生成的用于生产makefile的配置文件

#包含的模块
QT += core gui

#大于Qt4版本才包含widgets模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

#使用C++11的特性
CONFIG += c++11

#应用程序名 生成的.exe程序名
TARGET = QtFirst

#应用程序模板类型
TEMPLATE = app

#工程中包含的ui设计文件
FORMS += forms/painter.ui

#工程中包含的资源文件
RESOURCES += qrc/painter.qrc

#工程中包含的源文件
SOURCES += \
    main.cpp \
    mypushbutton.cpp \
    mywidget.cpp

#工程中包含的头文件
HEADERS += \
    mypushbutton.h \
    mywidget.h

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

关于模板变量变量的配置选项:

  1. app:建立一个应用程序的makefile,这是默认值,如果模板没有被指定,该选项将被使用。
  2. lib:建立一个库的makefile
  3. vcapp:建立一个应用程序的VisualStudio项目文件
  4. vclib:建立一个库的VisualStudio项目文件
  5. subdirs:特殊的模板,可创建一个能够进入特定目录、并且为一个项目文件生成makefile、并且为它调用make的makefile

4.Qt应用程序框架

#include "mywidget.h"
#include <QApplication>

int main(int argc, char *argv[]) {
    //1.创建应用程序对象a (在Qt中应用程序对象只能有一个)
    QApplication a(argc, argv);
    //2.创建窗口对象 w (窗口对象mywidget父类为QWidget)
    myWidget w;
    //3.调用窗口对象的show方法进行窗口显示
    w.show();
    //4.让应用程序对象进入消息循环(让代码阻塞在该行)
    return a.exec();
}
  • QApplication应用程序类:
    • 管理图形用户界面应用程序的控制流和主要设置
    • 是Qt的整个后台管理的核心包含主事件循环,在其中解决来自窗口系统和其他资源的所有事件处理和调度,也处理应用程序初始化和结束,并提供对话管理。
    • 对任何一个使用Qt图形用户界面的应用程序,都正好存在一个QApplication对象(不论此时该应用程序有多少窗口)。
  • a.exec():程序进入消息循环,等待对用户输入进行响应
    • main函数将控制权转交给Qt,由Qt完成事件处理工作,当应用程序退出的时候exec的值就会返回。
    • 在exec函数中Qt接受并处理用户和系统的事件,并且将它们传递给适当的窗口部件。

二、按钮创建

按钮其实就是一个QPushButton类下的对象,

并利用setParent为其指定一个依赖的父窗口,配合setText显示文字、move移动按钮位置、setWindowTitle修改窗口标题、resize指定窗口大小、setFixedSize设置固定窗口大小,

main.cpp

#include "mywidget.h"
#include <QApplication>

int main(int argc, char *argv[]) {
    //1.创建应用程序对象a (在Qt中应用程序对象只能有一个)
    QApplication a(argc, argv);
    //2.创建窗口对象 w (窗口对象mywidget父类为QWidget)
    myWidget w;
    //3.调用窗口对象的show方法进行窗口显示
    w.show();
    //4.让应用程序对象进入消息循环(让代码阻塞在该行)
    return a.exec();
}

mywidget.cpp

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

class myWidget : public QWidget {
    Q_OBJECT//Q_OBJECT宏 允许类中使用信号与槽的机制
public:
    myWidget(QWidget *parent = nullptr);
    ~myWidget();
};

#endif // MYWIDGET_H
#include "mywidget.h"
#include <QPushButton>

myWidget::myWidget(QWidget *parent):QWidget(parent){
    //1.设置主窗口属性
    resize(600, 400);//设置主窗口大小
    setWindowTitle("第一个窗口");//设置主窗口标题
    setFixedSize(600, 400);//设置主窗口大小固定
    \
    //2.创建并设置第一个窗口属性
    QPushButton *btn = new QPushButton;//创建一个按钮
    btn->setParent(this);//让btn对象依赖在mywidget窗口中显示
    btn->setText("QPushBtn1");//显示文本

    //3.创建并设置第二个窗口属性
    QPushButton *btn1 = new QPushButton("QPushBtn2", this);//按照控件大小创建窗口
    btn1->move(100, 0);//移动按钮位置
    btn1->resize(100, 30);//设置按钮的大小
}

myWidget::~myWidget(){ }

三、对象模型

1.对象树引入

QObject是以对象树的形式组织起来的

注意到Qt在按钮创建时都使用了new操作符在堆区开辟了内存,但是没有进行delete操作?因为其会自动释放,从而不需要delete操作,

在这里插入图片描述

在Qt中创建对象的时候会提供一个Parent对象指针,

  1. 当创建一个QObject对象时,其构造函数会接收一个QObject指针(parent父对象指针)作为参数,相当于在创建QObject对象时,可以为其提供一个父对象,创建的QObject对象会自动添加到父对象的children()列表中。
  2. 当父对象析构时children列表中的所有对象都会被析构,注意这里的父对象并不是继承意义上的父类,这种机制在 GUI 程序设计中相当有用(简化了内存回收机制)。例如按钮有一个QShortcut对象作为其子对象,当按钮被删除的时快捷键也会被删除。
  3. 当一个QObject对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过对象树中对象的顺序是没有定义的,这意味着销毁这些对象的顺序也是未定义的。
  4. 任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。

2.存在的问题

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

  • QObject在栈上创建Qt 保持同样的行为,正常情况下这不会发生什么问题:
{
    QWidget window;
    QPushButton quit("Quit", &window);
}

作为父组件的 window 和作为子组件的 quit 都是QObject的子类(事实上,它们都是QWidget的子类,而QWidget是QObject的子类)。这段代码是正确的,quit 的析构函数不会被调用两次,因为标准 C++要求局部对象的析构顺序应该按照其创建顺序的相反过程。因此这段代码在超出作用域时,会先调用 quit 的析构函数,将其从父对象 window 的子对象列表中删除,然后才会再调用 window 的析构函数。

  • 但如果将代码修改为下面的代码:
{
    QPushButton quit("Quit");
    QWidget window;
    quit.setParent(&window);
}

这里析构顺序就出现了问题,在上面的代码中作为父对象的 window 会首先被析构,因为它是最后一个创建的对象。

在析构过程中它会调用子对象列表中每一个对象的析构函数,也就是说 quit 此时就被析构了。代码继续执行在 window 析构之后,quit 也会被析构,因为 quit 也是一个局部变量,在超出作用域的时候当然也需要析构。但是这时候已经是第二次调用 quit 的析构函数了,C++ 不允许调用两次析构函数,因此程序崩溃了。

由此得知 Qt 的对象树机制虽然在一定程度上解决了内存问题,但是也引入了一些值得注意的问题。这些细节在以后的开发过程中需要注意,最好从开始就养成习惯:尽量在构造的时候就指定 parent 对象,并且大胆在堆上创建

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

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

相关文章

企业如何搭建矩阵内容,才能真正实现目的?

当下&#xff0c;新媒体矩阵营销已成为众多企业的营销选择之一&#xff0c;各企业可以通过新媒体矩阵实现扩大品牌声量、维持用户关系、提高销售业绩等不同的目的。 而不同目的的矩阵&#xff0c;它的内容运营模式会稍有差别&#xff0c;评价体系也会大不相同。 企业在运营某类…

性能优化-react路由懒加载和组件懒加载

背景 随着项目越来越大&#xff0c;打包后的包体积也越来越大&#xff0c;严重影响了首屏加载速度&#xff0c;需要对路由和组件做懒加载处理 主要用到了react中的lazy和Suspense。 废话不多说&#xff0c;直接上干货 路由懒加载 核心代码 import React, { lazy, Suspens…

精准感知+高效预判——城市“听诊器”防水患于未然

近期&#xff0c;全国多地遭遇暴雨猛袭&#xff0c;引发城市积涝&#xff0c;更有台风“杜苏芮”登陆后引发沿海内陆极端降水&#xff0c;各地排水防涝工作面临严峻考验。 快速定位城市排水管网系统的管道淤堵点&#xff0c;对河道水位、雨量情况、污水厂进水流量以及泵站运行情…

【云原生K8s】二进制部署单master K8s+etcd集群

一、实验设计 mater节点master01192.168.190.10kube-apiserver kube-controller-manager kube-scheduler etcd node节点node01192.168.190.20kubelet kube-proxy docker (容…

HTTP(超文本传输协议)学习

关于HTTP补学 一、HTTP能干什么 通过下图能够直观的看出&#xff1a;“交换数据 ” 二、HTTP请求例子 一个 HTTP 方法&#xff0c;通常是由一个动词&#xff0c;像 GET、POST 等&#xff0c;或者一个名词&#xff0c;像 OPTIONS、HEAD 等&#xff0c;来定义客户端执行的动作。…

Centos7.x修改密码

Centos7.x修改密码 root修改自己的密码 云服务器 云服务器则直接在控制台修改(例如阿里云服务器直接在阿里云服务器控制台修改&#xff0c;不赘述)命令行方式: 命令行输入: passwd 再两次输入新密码 root修改普通用户的密码 命令行方式: passwd 用户名再输入新的密码 普…

深入理解TCP三次握手:连接可靠性与安全风险

目录 导言TCP简介和工作原理的回顾TCP三次握手的目的和步骤TCP三次握手过程中可能出现的问题和安全风险为什么TCP三次握手是必要的&#xff1f;是否可以增加或减少三次握手的次数&#xff1f;TCP四次挥手与三次握手的异同点 导言 在网络通信中&#xff0c;TCP&#xff08;Tra…

7个更好用的数据可视化工具,建议收藏

在数据可视化工具的帮助下&#xff0c;设计师可以将数据转化为图像进行表达&#xff0c;让数据更加直观&#xff0c;更容易理解。今天本文会与打击分享7个好用的数据可视化工具&#xff0c;一起来get更好用的数据表达方式吧&#xff01; 1、即时设计 即时设计是一个非常受欢迎…

【js】FormData方法介绍和使用:

文章目录 一、接口使用FormData提交数据&#xff1a;二、FormData概述&#xff1a;三、FormData案例&#xff1a; 一、接口使用FormData提交数据&#xff1a; 二、FormData概述&#xff1a; 三、FormData案例&#xff1a; let formData new FormData() for (const key in tha…

一篇聊聊JVM优化:堆

一、Java 堆概念 1、简介 对于Java应用程序来说&#xff0c;Java堆&#xff08;Java Heap&#xff09;是虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享 的一块内存区域&#xff0c;在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例&#xff0c;Java 世界…

成为“黑客“前,必须经过的“学习路线“!!!

成为"黑客"前&#xff0c;必须经过的"学习路线"&#xff01;&#xff01;&#xff01; 最近很多小伙伴在看了我的文章后&#xff0c;有一个共同的问题&#xff0c;"我们是小白&#xff0c;我们没有基础&#xff0c;我们如何通过自学&#xff0c;就可…

vue3数组V-for中动态生成$refs

vue3数组V-for中动态生成$refs 在项目实际需求中&#xff0c;可能会遇到使用数组动态生成$refs,根据官方参考&#xff0c;采用了以下方式实现 <template><div class"content"><ul v-for"(item, index) in editableTabs" :key"item.n…

2023全网最全的爆款抓包工具,各有千秋

在处理IP网络的故障时&#xff0c;经常使用以太网抓包工具来查看和抓取IP网络上某些端口或某些网段的数据包&#xff0c;并对这些数据包进行分析&#xff0c;定位问题。 在 IMON项目里&#xff0c;使用抓包工具抓包进行分析的场景在EPG采集、引流模块和软终端监看模块&#xff…

【练】创建两个线程:其中一个线程拷贝图片的前半部分,另一个线程拷贝后半部分

方法一&#xff1a; 先在主函数创建并清空拷贝的目标文件&#xff0c;再创建两个线程&#xff0c;在两个线程内部同时打开要读取的文件以及要拷贝的目标文件&#xff08;两个线程不共用同一份资源&#xff09;。 使用到的函数&#xff1a; 标准IO函数&#xff08;fprintf&…

(数据库系统概论|王珊)第一章绪论-第一节:数据库系统概论

目录 一&#xff1a;四大基本概念 &#xff08;1&#xff09;数据(Data) &#xff08;2&#xff09;数据库(DataBase,DB) &#xff08;3&#xff09;数据库管理系统(DataBase Management System,DBMS) &#xff08;4&#xff09;数据库系统(Database System&#xff0c;DBS…

HBN:2023年原生白护肤白皮书(附下载)

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 调研数据表明&#xff0c;近九成的消费者对自己肤色不满&#xff0c;其中偏黄、偏黑是大家的核心困扰&#xff08;图1-1&#xff09;。在此情况下&#xff0c;“美白” 在各社媒平台的搜素量近年来一…

开利网络受邀出席数利丰应用研讨会 分享企业数字化转型落地经验

数利丰应用研讨会在广州举办。本次研讨会的主题为「聚焦数据价值&#xff0c;引领数字转型」。 广州市开利网络科技有限公司总经理、和合生态联合发起人付立军先生受邀出席研讨会并同在座40余国内外企业创始人与高管共同探讨企业经营所面临的共性问题&#xff0c;分享在企业数…

【力扣】19. 删除链表的倒数第 N 个结点 <链表指针、快慢指针>

【力扣】19. 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n…

【java安全】原生反序列化利用链JDK7u21

文章目录 【java安全】原生反序列化利用链JDK7u21前言原理equalsImpl()如何调用equalsImpl()&#xff1f;HashSet通过反序列化间接执行equals()方法如何使hash相等&#xff1f; 思路整理POCGadget为什么在HashSet#add()前要将HashMap的value设为其他值&#xff1f; 【java安全】…

毫米波雷达 TI IWR6843 官方测试程序(Out Of Box Demo)

1.硬件准备 1.IWR6843AOP板子 2.两个USB转串口模块&#xff08;因为我的是自己做的板子&#xff0c;板子上没有集成USB转串口芯片&#xff09; 2.软件准备 1.最新版本的CCS&#xff0c;注意后缀没有THEIA https://www.ti.com/tool/CCSTUDIO?DCMPdsp_ccs_v4&HQSccs 2.最…