对象树
qt使用对象树进行对象管理,方便内存管理
作为树状图,那就会存在分岔(父对象和子对象)。
1.当创建一个QObject对象的时候,创建一个父对象指针给构构造函数,会自动添加到该对象的父对象的children()列表下面,当父对象析构的时候,父对象的所有子对象都会析构(当用户关闭以一个对话框的时候,会将对话框的所有内容全部删除)
2.当析构子对象的时候,会从父对象的子对象列表中删除。(优点:自动销毁子类对象,不需要管控内存情况)(在对话框删除一个工具栏,但自动调整屏幕显示)

3.只要对象定义于QObject或者继承于QObject,就不用delete对象,因为QObject是这一切的基类。
4.QWidget是能够在屏幕上显示的一切组件的父类,继承于QObject。
5.堆区对象树的构造和析构:构造顺序是:父对象->子对象,而析构顺序是:子对象->父对象,但在运行程序发现,构造和理论推算一样,但是析构却和理论相反,原因是:析构是从父对象开始打印Qdebug()的相关信息,直到枝叶尽头,然后从最后创建的子对象开始,往回开始析构。这个时候才开始释放内存
千万注意:析构 ≠ 释放!!!!!!
6.子对象只能对应一个父对象,父对象可以对应对各子对象。
7.对象树的相关疑惑问题:
(a).在堆区:如果子对象在父对象的前面创建,就会析构两次子对象(父对象一次,子对象一次),从而出现程序的报错。 栈区不允许顺序出错,否则会crash。
(b).当顺序正常的时候,栈区先析构子对象同时释放内存,然后是父对象同时释放内存。
信号与槽(Signal and Slot)
我用的是Qt5版本,所以connect函数已经将信号与槽连接在了一起,不需要使用SIGNAL()和SLOT()。

QT 与 槽 的连接机制
(1)信号与槽式QT对象之间的通信,可以通过某种触发或者代码触发。
(2)信号和槽的连接式动态的,对象释放后会自动断开所有的信号和槽,所以基本不会使disconnect()。
(3)QObject::connect(发送信号对象的地址,信号,接收信号的对象,槽函数)
(4)存在一对一,多对一,一对多情况
my_widget.cpp
- #include "my_widget.h"
- #include"QPushButton"
- my_Widget::my_Widget(QWidget *parent)
- : QWidget(parent)
- {
- QPushButton *btn = new QPushButton;
- btn->show(); //show以顶层方式弹出窗口
- //让 my_widget 依赖在窗口
- btn->setParent(this);
- //显示文本
- //btn->resize(200,200);
- btn->setText("第一个按钮");
-
- //;创建第二个文本
- QPushButton *btn2 = new QPushButton("第二个按钮",this);
- btn2->move(100,200);
- resize(600,400);
- //设置窗口的大小和标题
- setFixedSize(600,400);
- setWindowTitle("text");
- //需求 按钮关闭窗口 参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接受者 参数4 处理的曹函数
- connect(btn,&QPushButton::clicked,this,&my_Widget::close);
- }
my_widget.h
- t : public QWidget
- {
- Q_OBJECT
-
- public:
- my_Widget(QWidget *parent = nullptr);
- ~my_Widget();
- };
- #endif // MY_WIDGET_H
- signals:
- //自定义信号 写到signals下
- //返回值 为 void ,只需要声明,不需要实现
- //可以有参数,可以重载
- void hungry();
-
- void hungry(QString namefood);
-
-
-
- public slots:
- //返回为void , 需要声明和实现
- void treat();
- void treat(QString namefood);
当出现同名的析构函数的时候,需要用函数指针进行传址。然后用connect进行连接
- void (Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
- void (Student:: *studentSlot)(QString) = &Student::treat;
-
-
- connect(btn,&QPushButton::clicked,this,&Widget::classIsOver);
Lambda表达式
使用Lambda表达式可以简化代码操作,可以直接对槽函数进行值传递。
- QPushButton *but1 = new QPushButton(this);
- QPushButton *but2 = new QPushButton(this);
- but1->move(100,100);
- int n = 10;
- connect(but1,&QPushButton::clicked,this,[n]()mutable{n = 100+10;qDebug()<
- connect(but2,&QPushButton::clicked,this,[=](){qDebug()<
思考:当按键but1按下时打印110,当按键but2按下的时候,n竟然还是10?
原因:因为mutable传进去的只是n的一个拷贝对象,而不是本尊,所以不会影响到别的地方调用。
-
相关阅读:
局域网MongoDB的数据库访问不了
Python中setdefault()通过键查找字典中对应的值
基于Python实现的手写数字图像识别
Rust基础入门之(基本类型)
Roreg复现
Socks5代理IP:网络安全的重要组成部分
JAVA计算机毕业设计-物流管理系统-(附源码、数据库)
react源码分析:babel如何解析jsx
代码改造:设计模式之责任链
树模型(2)随机森林
-
原文地址:https://blog.csdn.net/weixin_63032791/article/details/127569028