day01C++QT框架学习
/*快捷注释ctrl + ?*/
学习QT的基本框架
class Widget : public QWidget //这段代码会在创建一个QTApplication的时候被创建
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();//声明Widget的析构
};
#endif // WIDGET_H
Widget::Widget(QWidget *parent)
: QWidget(parent)//表明Widget是QWidget的子类 Widget可以继承父类的功能
{
//创建按钮
QPushButton * btn = new QPushButton;//提示unused 没有引用
//这里我们只是创建了一个新的按钮但是没有让它显示出来
//我们调用show方法使它弹出
btn->show();
//show()顶层方式弹出 不在Widget窗中弹出
//发现我们创建的新的按钮不在Widget窗口中,而是新生成了一个窗口
//设置父亲,使用this指针,this指针永远指向当前类,
btn->setParent(this);//设置当前按钮的父类是this指针指向的当前类Widget 而当前类Widget的父类是QWidget所以按钮可以使用QWidget类库中的功能
//注意以上两种方式都可以显示出button但同时调用两种方法程序不会报错,但会导致窗口不显示。
//设置按钮中的文字
btn->setText("退出");//将char* 隐式类型转换为Qstring
//创建按钮的第二种方式
QPushButton * btn2 = new QPushButton("第二个按钮", this);
//创建这种按钮会发现按钮和创建的窗口大小相同
//重置窗口大小
this->resize(600,400); //void resize(int w, int h)左宽右高
//取消注释第一个按钮,发现后写的按钮会覆盖住先写的按钮
//注意这里其实第一个按钮是没有显示的只会显示第二个按钮,因为一个按钮同时调用了两种显示方法,会出现歧义,这里我们返回到调用show()方法的地方把那句话注释掉。
//移动第二个按钮调用move方法
btn2->move(100, 300);//move(int x, int y) X轴坐标和y轴坐标
//按钮重置大小 也是调用resize 方法
btn2->resize(100, 100);
//重置窗口标题
setWindowTitle("Qt的第一个窗口");
//设定固定的窗口大小窗口不能再任意扩大和缩小
setFixedSize(300,600);
//Fixed固定的 html中固定的侧边栏也是Fix关键字方便记忆
//QT在一定程度下简化了内存回收机制
//当点击叉关闭窗口后,会自动的释放内存
//创建自己的按钮
MyButton* myBtn = new MyButton;
myBtn->setText("我的第一个按钮");
myBtn->move(200, 200);
myBtn->setParent(this);//显示按钮
//必须加在children表里面才会进行内存的回收
//坐标系 以窗口左上角为原点,向右为X轴正方向,向下为Y轴正方向
}
Widget::~Widget()
{
qDebug() << "Widget析构了";
//我们发现是先打印的"Widget析构了"再打印“MyButton”的析构”
//发现打印顺序与结论不相同。
//析构函数的创建顺序与构造函数的创建顺序相反
//因为在程序结束时,是先找父类析构函数输出后,找他的儿子的析构函数输出,他的儿子输出完以后输出孙子如果没有孙子,则在打印完儿子析构的内容后就会被释放掉内存
//导致在创建析构函数时顺序与new对象的顺序相反,但是在执行析构函数时顺序与new对象时的顺序相同
//结论是对象树在new的对象是一层一层的往下创建的,delect是从底层往上一层一层的回收
}
零散的笔记
QPushButton * btn(对象名) = new QPushButton (新的对象)
qDebug() << "输出语句";
//在QT框架中的输出语句 与C++中的cout用法类似,但是得在头文件中添加<QDebug>文件
btn.show();
btn.setParent(this);
//两种显示方式
btn.move(int x, int y);//x轴坐标 y轴坐标
Widget.Fixedresize(int w, int h);//宽度weight、高度height
QCreater
/
/
Qwidget
/ \
/ \
btn MyButton
//创建的时候由上往下进行new操作
//点击“×”释放内存的时候是由先从下往上进行delect操作
百度查询内容
析构:
在程序释放内存时,会可以构建析构从而在释放内存时先执行析构的内容然后再去执行。
析构函数是特殊的类成员函数,简单来说,析构函数与构造函数的作用正好相反,它用来完成对象被删除前的一些清理工作,也就是专门的扫尾工作。如果构造函数打开了一个文件,最后不需要使用时文件就要被关闭,析构函数允许类自动完成类似清理工作,不必调用其他成员函数。
按照这个逻辑在执行析构的顺序应该是先执行btn的析构,因为btn是最先被释放的,然后执行Qwidget的析构。
逻辑没有错
但是在执行析构的时候会先寻找对象树的祖先,从根节点开始执行,所以在执行析构时的顺序时跟new对象的顺序是一样的
简而言之,在执行析构时会先执行Qwidget的析构,然后执行btn的析构函数。
对象树
QObeject
/ | \
/ | \
QWidget QWidget QWidget
C++中规定了析构顺序应该按照其创建顺序的相反过程。那么问题来了,如果我们先创建了子对象,再创建的父对象,根据上述原理析构的时候先析构父对象,又因为Qt中的对象树自动析构原理,我们析构父对象会自动析构子对象。也就是说, 子对象此时就被析构了,然后代码继续执行,按照顺序还要再析构一次子对象,但是这时候已经是第二次调用
子对象的析构函数了,C++中不允许调用两次析构函数,因此,程序会崩溃。
本文来自博客园,作者:华岁渡春风,转载请注明原文链接:https://www.cnblogs.com/orsrrc/p/16189794.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本