一、使用Label显示Hello World
1.ui设计
可以在Qt Designer中拖拽方式进行创建
2.代码方式
在myqwidget.cpp文件中添加下列代码
二、对象树
我们在堆上创建了QLabel类的对象。但是我们没有去delete,这样会产生内存泄漏吗?
答案是不会。label对象会在合适的时候(窗口被关闭或者被销毁)被析构释放(虽然没有手动写delete,但确实能释放)
为什么?
原因在于这个this。之所以能够把对象释放掉,主要是因为把这个对象挂在了对象树上。
前端开发(网页开发)也涉及到 类似的 对象树(DOM),本质也是一个树形结构(N叉树),通过树形结构把页面上的各种元素组织起来
Qt中也是类似,也是搞了一个对象树,N叉树,把界面上的各种元素组织起来了。
所以此处用new的方式创建对象,也就是把这个对象的生命周期交给Qt的对象树统一管理
当把对象改成在栈上创建,此时就可以看到,运行起来的程序就无法显示出我们所创建的label对象,此时label对象随着析构函数的结束,就销毁了。
模拟实现Qt自动释放对象机制
创建一个自定义的类,最主要的目的,是自定义一个析构函数,在析构函数中,完成打印,方便咱们看到最终的自动销毁对象树的效果
这是创建的MyQLabel类的头文件
小技巧:
1.在Qt Creator中,可以通过 F4 切换头文件和对应的 .cpp文件。
这是C++ IDE的常规功能
(比如在 Vim 中可以通过 :A 的方式来完成切换,也可以使用 :AT 的方式新开一个标签页来显示)
2.在点击成员函数上,按Alt+回车,再按回车,会自动生产.cpp文件中成员函数实现。
在mywidget.cpp文件中定义对象,并传this。
使用自己定义的MyQLabel代替原来的QLabel,所谓的 “继承” 本质上是拓展,保持原有功能不变的基础上,给对象扩展出一个析构函数,通过这个析构函数,打印一个自定义的日志,方便我们观察程序运行效果。
在myqlabel.cpp文件中,我们在析构函数中打印一条日志消息,
来让我们看看效果,注意:此时输出什么也没有
当我们关闭这个对话框时
就会出现一条消息。但是这个消息是乱码的。
但是日志消息是有的,说明析构函数是执行了。
虽然没有手动delete,但是由于把MyQLabel挂到了对象树上,此时窗口被销毁的时候,就会自动销毁对象树中的所有对象,MyQLabel的析构是执行到了。
而乱码这个事情,我们以后会经常涉及到,乱码问题出现的原因,有且仅有一个(不局限于C++),就是编码方式不匹配。
目前,表示汉字字符集,主要是两种方式
- GBK,(中国大陆)使用2个这字节表示一个汉字,Windows简体中文版,默认的字符集就是GBK
- UTF-8/ utf8 变长编码,表示一个符号使用的字节数有变化,2-4,但是在utf8中,一个汉字。一般是3个字节。Linux默认就是utf8
如果你字符集本身是utf8编码的,但是终端(控制台)是按照gbk方式来解析显示的,此时就会出现乱码(拿着utf8的数值,去查询gbk的码表),此时就会出现乱码了!
那么如何查看当前文件是如何编码的呢?
先找到当前文件所处路径的文件夹,用记事本打开,就可以查看了。
如果显示的是UTF-8,就说明这个文件是用utf8进行编码的
如果显示的是ANSI,就说明这个文件是用GBK方式进行编码的。
而我们这个Qt 终端控制台的编码方式没有查询到。
所以Qt提供了一个函数,专门来打印消息qDebug().需要一个头文件,QDebug自动换行
qDebug是一个宏,封装了QDebug类的对象。
qDebug打印的调试日志,是可以统一进行关闭的。
三、使用Line Edit方式显示Hello World
可以通过Qt Designer中拖拽控件进行添加
代码方式
四、通过按钮方式显示Hello World
ui中,Push Button就是一个普通按钮,如果想用,就可以使用拖拽
在Qt Designer中创建一个控件的时候,此时就会给这个控件分配一个objectName属性。
这个属性的值,要求是在界面中是唯一的(不能和别的控件重复)
qmake在预处理.ui文件的时候,就会根据这里的objectName生产对应的C++代码
C++代码中该QPushbutton对象的变量名字就是这里的objectName。这个变量就是ui属性的成员变量。
纯代码方式:
在mywidget.h文件中定义成员变量MyButton 和 成员函数 Headler,在.cpp中实现
五、Qt窗口坐标系
坐标体系:以左上角为原点(0,0),X向右增加,Y向下增加。
move函数,用于调正控件的位置