ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

QT开发基础

2021-02-15 15:33:07  阅读:265  来源: 互联网

标签:窗口 QT 对象 QPushButton 基础 QObject 开发 析构


QT开发

文章目录


前言

走进QT的大门,从这里开始
QT下载:http://download.qt.io/

1.特点

跨平台
接口简单,易上手,学习QT框架对学习其他框架有参考意义
开发效率高(继承多态)
一定程度上简化了内存回收机制
有很好的社区氛围
可以进行嵌入式开发

2.QT creator使用

1.选择合适的基类:
父类 Qwidget 精简版窗口
子类 QMainWindow 带菜单栏的窗口
子类 QDialog 对话框
在这里插入图片描述
2.QT助手是最靠谱的文档
点击索引即可查找需要的控件,前提是记住控件名称,比如按钮的名称为QPushButton,QT助手关于QPushButton的描述:
Contents
• Properties
• Public Functions //公共函数
• Reimplemented Public Functions //公共槽函数
• Public Slots
• Static Public Members
• Protected Functions
• Reimplemented Protected Functions
• Detailed Description

QPushButton Class
The QPushButton widget provides a command button. More…
Header: #include //头文件
qmake: QT += widgets //所在的模块
Inherits: QAbstractButton //父类(当前类不存在的性质多半继承自长辈,所以可以在长辈类中查找)
Inherited By: QCommandLinkButton //子类
• List of all members, including inherited members
• Obsolete members

3.解决窗口乱码问题
默认编码选择UTF-8(注意在新建的工程有效)
在这里插入图片描述

3.工程

1.pro工程文件

QT       += core gui	#core包含的模块,类比于操作系统中的内核	gui页面显示的核心代码

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

#TARGET = richard		#应用程序名	生成的.exe文件
#TEMPLATE = app			#模板类型	为 应用程序模板

# 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

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

还会有其他选项比如:

FORMS += forms/painter.ui			#工程中包含的.ui设计文件
RESOURCES += qrc/painter.qre	#工程中包含的资源文件

2.按钮示例
所需的方法都可以在Qt助手中找到,比如移动按钮位置,方法在他的爷爷类中。
在这里插入图片描述
main.cpp:

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    //QApplication应用程序类,初始化我们的应用程序
    QApplication a(argc, argv);

    //创建一个主窗口控件
    Widget w;
    //显示主窗口,hide隐藏窗口(窗口默认是隐藏的,所以创建了之后一定要调用show)
    w.show();

    //a.exec()主事件循环(带阻塞 等待用户操作界面)widget.cpp
    return a.exec();
}

widget.cpp:

#include "widget.h"
#include <QPushButton>

//界面的设计在这,窗口控件的构造函数中
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //this代表当前主窗口
    this->setWindowTitle("第一个窗口");
    //固定窗口(默认是窗口大小可以拉的)
    //this->setFixedSize(800,600);  //窗口不可以拖动
    //设置窗口大小
    this->resize(400,300);      //窗口可以拖动

    //在窗口上放一个按钮,包含头文件,qmake中增加模块QT += widgets	(默认是添加了的),(QT助手)
    //parent父对象(和父类的概念不同,表示button将来希望被谁接管)this表示button放到当前窗口,将来负责析构button,
    //所以button下面是不需要显式调用delete的,也不需要调用~QPushButton析构函数
    QPushButton *button1 = new QPushButton("跟屁虫",this);
    //用new的好处:下面的对象树会讲,用局部变量,栈来存储会有什么坏处

    //如下分开设置
    QPushButton *button2 = new QPushButton;
    button2->setParent(this);
    button2->setText("Richard");
    //默认控件会显示到主窗口左上方,会覆盖button1
    //移动,move函数在QPushButton的爷爷类中
    button2->move(400,300);     //刚好被挡住,拖动窗口显示按钮
}

Widget::~Widget()
{
}

3.对象数
一句话概括就是子对象会被交由父对象接管,关闭程序时父对象会负责清理子对象留下的垃圾。如上述代码。
关于对象树的解释来自这篇文章:https://www.cnblogs.com/gd-luojialin/p/9215707.html(网站上存在大量的抄袭现象,这篇是我找到的中时间最早的,可能是原创,如有侵权请告知)
在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。

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

 当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是 parent,也就是父对象指针。

这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。

 当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类!)

这种机制在 GUI 程序设计中相当有用。例如,一个按钮有一个QShortcut(快捷键)对象作为其子对象。当我们删除按钮的时候,这个快捷键理应被删除。这是合理的。

 QWidget是能够在屏幕上显示的一切组件的父类。

 QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的时候,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此,因为这些都是对话框的子组件。

 当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。比如,当我们删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。

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

 当一个QObject对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。

 任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。

如果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 的对象树机制虽然帮助我们在一定程度上解决了内存问题,但是也引入了一些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰一下,所以,我们最好从开始就养成良好习惯,在 Qt 中,尽量在构造的时候就指定 parent 对象,并且大胆在堆上创建。

标签:窗口,QT,对象,QPushButton,基础,QObject,开发,析构
来源: https://blog.csdn.net/weixin_44705391/article/details/113813730

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有