目录
一、使用qt实现hello world
1.1 图形化方式
1.2 纯代码构建
编辑
二、对象树
三、乱码问题
四、小结
一、使用qt实现hello world
1.1 图形化方式
双击widget.ui 文件
拖拽控件至ui界面窗口并修改内容;
构建并运行,效果如下所示:
然后我们进入explore到文件管理器里面查看下面这个文件直接拖拽到qt里面。
1.2 纯代码构建
我们先进入widge.cpp文件中。
构建运行就行,只不过是在左上角。
但是我们这里有一个问题,这里我们new了一个对象之后,没有进行delete?这样难道不会出现内存泄漏吗?
关注内存泄漏,是要融入DNA里面的。
内存泄漏是一个非常可怕,非常严重的事情!!
这种问题不容易第一时间发现。
上述代码,在qt中不会产生内存泄漏。
label对象会合适的时候被析构释放~~(虽然没有写,但是确实能释放)
之所以能够把对象释放掉,主要是因为把这个对象挂载到了对象树上面。
二、对象树
在Qt中创建很多对象的时候会提供⼀个Parent对象指针,下⾯来解释这个parent到底是⼲什么的。
•QObject是以对象树的形怯组织起来的。
o当创建⼀个QObject对象时,会看到QObject的构造函数接收⼀个QObject指针作为参数,这个参数就是parent,也就是⽗对象指针。
o这相当于,在创建QObject对象时,可以提供⼀个其⽗对象,我们创建的这个QObject对象会⾃动添加到其⽗对象的children()列表。
o当⽗对象析构的时候,这个列表中的所有对象也会被析构。(注意,这⾥的⽗对象并不是继承意义上的⽗类!)
这种机制在GUI程序设计中相当有⽤。例如,⼀个按钮有⼀个QShortcut(快捷键)对象作为其⼦对象。当删除按钮的时候,这个快捷键理应被删除。这是合理的。
•QWidget是能够在屏幕上显⽰的⼀切组件的⽗类。
oQWidget继承⾃QObject,因此也继承了这种对象树关系。⼀个孩⼦⾃动地成为⽗组件的⼀个⼦组件。因此,它会显⽰在⽗组件的坐标系统中,被⽗组件的边界剪裁。例如,当⽤户关闭⼀个对话框的时候,应⽤程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该⼀起被删除。事实就是如此,因为这些都是对话框的⼦组件。
o当然,我们也可以⾃⼰删除⼦对象,它们会⾃动从其⽗对象列表中删除。⽐如,当我们删除了⼀个⼯具栏时,其所在的主窗⼝会⾃动将该⼯具栏从其⼦对象列表中删除,并且⾃动调整屏幕显⽰。
Qt引⼊对象树的概念,在⼀定程度上解决了内存问题。
•当⼀个QObject对象在堆上创建的时候,Qt会同时为其创建⼀个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
•任何对象树中的QObject对象delete的时候,如果这个对象有parent,则⾃动将其从parent的children()列表中删除;如果有孩⼦,则⾃动delete每⼀个孩⼦。Qt保证没有QObject会被delete两次,这是由析构顺序决定的。
如果QObject在栈上创建,Qt保持同样的⾏为。正常情况下,这也不会发⽣什么问题。来看下⾯的代码⽚段:
作为⽗组件的window和作为⼦组件的quit都是QObject的⼦类(事实上,它们都是QWidget的⼦类,⽽QWidget是QObject的⼦类)。这段代码是正确的,quit的析构函数不会被调⽤两次,因为标准C++要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作⽤域时,会先调⽤quit的析构函数,将其从⽗对象window的⼦对象列表中删除,然后才会再调⽤window的析构函数。
但是,如果我们使⽤下⾯的代码:
情况⼜有所不同,析构顺序就有了问题。我们看到,在上⾯的代码中,作为⽗对象的window会⾸先被析构,因为它是最后⼀个创建的对象。在析构过程中,它会调⽤⼦对象列表中每⼀个对象的析构函数,也就是说,quit此时就被析构了。然后,代码继续执⾏,在window析构之后,quit也会被析构,因为quit也是⼀个局部变量,在超出作⽤域的时候当然也需要析构。但是,这时候已经是第⼆次调⽤quit的析构函数了,C++不允许调⽤两次析构函数,因此,程序崩溃了。
由此我们看到,Qt的对象树机制虽然在⼀定程度上解决了内存问题,但是也引⼊了⼀些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰⼀下,所以,我们最好从开始就养成良好习惯
💡在 Qt 中,尽量在构造的时候就指定 parent 对象,并且⼤胆在堆上创建。
Qt对象树如图:
对象树大概:
啥也没有。
这里我们新建一个文件,选择cpp,和cpp类。
需要我们手动包头文件。
成功构建了,但是日志有点问题。
三、乱码问题
为什么会出现乱码呢?
字符 编码/解码 - 锤子在线工具
挺好的无广告,纯净。
如何查看编码格式呢?点击explore
日志正常了。
四、小结
1、认识QLebal类,能够在界面上面显示字符串。
通过setText来设置的。参数QString(Qt中把cpp里面很多容器,进行了重新封装,历史原因)。
2、内存泄漏/文件资源泄漏
3、对象树。Qt中通过对象树,来统一的释放界面的控件对象。
Qt还是推荐使用new的方式在堆上创建对象,通过对象树,统一释放对象。
创建对象的时候,在构造函数中,指定父对象(此时才会挂载到对象树中)
4、通过继承自Qt内置的类,就可以达到对现有控件功能进行扩展效果。
Qt内置的QLabel,没法看到销毁的过程。为了看清楚,就创建类mylabel继承Qlabel
重写 析构函数
在析构函数中,加上日志,直观的观察到对象的释放过程了:
也可以在重写控件中的任何功能,不仅仅是析构函数~~达到功能扩张目的~~
5、乱码问题和字符集
6、如何在Qt中打印日志,作为调试信息。
使用cout固然可以,但是并不是上策(字符编码处理的不够好,也不方便统一进行关闭)
Qt中推荐使用qDebug()完成日志的打印。