当前位置:首页 » 《资源分享》 » 正文

[Qt][初识Qt]详细讲解

27 人参与  2024年09月08日 10:01  分类 : 《资源分享》  评论

点击全文阅读


目录

1.Qt命名规范2.Qt窗口坐标体系3.Qt文件4.容器:QT VS STL5.基类6.认识对象模型(对象树)1.是什么?2.解决内存问题1.如何解决?2.如何做? 3.举例说明4.总结 7.Qt父子对象8.Qt中乱码的处理9.注意 && 提要


1.Qt命名规范

类名:⾸字⺟⼤写,单词和单词之间⾸字⺟⼤写函数名及变量名:⾸字⺟⼩写,单词和单词之间⾸字⺟⼤写

2.Qt窗口坐标体系

坐标体系:以左上⻆为原点 ( 0 , 0 ) (0,0) (0,0),X向右增加,Y向下增加
请添加图片描述

对于嵌套窗⼝/控件,其坐标是相对于⽗窗⼝/控件来说的


3.Qt文件

Qt系统提供的标准类名声明头⽂件没有.h后缀Qt⼀个类对应⼀个头⽂件,类名就是头⽂件名QApplication为应⽤程序类,一个程序有且仅有一个 QApplication管理图形⽤⼾界⾯应⽤程序的控制流和主要设置QApplication是Qt的整个后台管理的命脉,它包含: 主事件循环,在其中来⾃窗⼝系统和其它资源的所有事件处理和调度它也处理应⽤程序的初始化和结束,并且提供对话管理 对于任何⼀个使⽤Qt的图形⽤⼾界⾯应⽤程序,都正好存在⼀个QApplication对象,⽽不论这个应⽤程序在同⼀时间内是不是有0、1、2或更多个窗⼝

4.容器:QT VS STL

Qt在早些年为了开发顺畅,自己造轮子搞了一系列的基础类,来支持Qt开发 例如QString, QVector, QList, QMap 但是现如今的STL和QT的基础类都打磨的很好了,所以在进行Qt开发的时候,如果需要用到上述容器类,可以使用STL容器,也可以使用Qt自己搞得这一套容器 但是Qt原生的API中,涉及到的接口,用的都是Qt自己的这一套容器 后续代码中,还经常会见到QString这样的一些东西,而很少见到std::string 注意QStringstd::string之间能很方便的相互转换 实际上QString用起来要比std::string香一些 因为QString内部已经对于字符编码做了处理,而std::string啥都没干

5.基类

QObject是Qt内置的⽗类.Qt中提供的很多类都是直接或者间接继承⾃QObject

对于基类的选择,⽬前有三种基类

基类说明
QMainWindow主窗⼝类,⼀般⽤于较为复杂的应⽤程序,除了中央客⼾区界⾯,还包括菜单栏、⼯具栏、 状态栏以及多个可停靠的⼯具对话框等
QWidget最简单、最基本的窗体程序,⾥⾯可以放置多个控件实现程序功能
QDialog基于对话框的程序,对话框⼀般⽤于弹窗,也可以⽤于主界⾯显⽰。对话框是从QWidget继 承⽽来的,并丰富了⼀些功能,如模态显⽰和返回值等

基类之间的关系
请添加图片描述


6.认识对象模型(对象树)

1.是什么?

在Qt中创建很多对象的时候会提供⼀个Parent对象指针QObject是以对象树的形式组织起来的 当创建⼀个QObject对象时,会看到QObject的构造函数接收⼀个QObject指针作为参数,这个参数就是parent,也就是⽗对象指针 这相当于,在创建QObject对象时,可以提供⼀个其⽗对象,创建的这个QObject对象会⾃动添加到其⽗对象的children()列表当⽗对象析构的时候,这个列表中的所有对象也会被析构(这⾥的⽗对象并不是继承意义上的⽗类) 使用对象树,把内容组织起来,最主要的目的是为了能够在合适的时机(窗口关闭/销毁),把这些对象统一进行释放Qt对象图
请添加图片描述

2.解决内存问题

1.如何解决?

Qt引⼊对象树的概念,在⼀定程度上解决了内存问题 当⼀个QObject对象在堆上创建的时候,Qt会同时为其创建⼀个对象树 不过,对象树中对象的顺序是没有定义的,这意味着,销毁这些对象的顺序也是未定义的 任何对象树中的QObject对象delete的时候 如果这个对象有parent,则⾃动将其从parentchildren()列表中删除如果有孩⼦,则⾃动delete每⼀个孩⼦ Qt保证没有QObject会被delete两次,这是由析构顺序决定的

2.如何做?

创建对象的时候,在构造函数中,指定父对象,此时该对象才会被挂到对象树上 如果该对象没有被挂到对象树上,就必须要记得手动释放 尽量避免在栈上创建Qt对象,可能存在提前释放的问题 如果QObject在栈上创建,Qt保持同样的⾏为,正常情况下,这也不会发⽣什么问题如下代码,没问题 作为⽗组件的window和作为⼦组件的quit都是QObject的⼦类quit的析构函数不会被调⽤两次,因为标准C++要求,局部对象的析构顺序应该按照其创建顺序的相反过程因此,这段代码在超出作⽤域时,会调⽤quit的析构函数,将其从⽗对象window的⼦对象列表中删除,然后才会再调⽤ window的析构函数
QWidget window;QPushButton quit("Quit", &window);
如下代码,有问题 情况有所不同,析构顺序出现了问题,作为⽗对象的window会⾸先被析构,因为它是最后⼀个创建的对象在析构过程中,它会调⽤⼦对象列表中每⼀个对象的析构函数 也就是说,quit此时就被析构了 然后,代码继续执⾏,在window析构之后,quit也会被析构 因为quit也是⼀个局部变量,在超出作⽤域的时候当然也需要析构但是,此时已经是第⼆次调⽤quit的析构函数了 C++不允许调⽤两次析构函数,因此,程序崩溃了
QPushButton quit("Quit");QWidget window;quit.setParent(&window);
在Qt中,尽量在构造的时候就指定parent对象,并且⼤胆在堆上创建 通过new的方式创建对象,是为了把这个对象的生命周期交给Qt的对象树来统一管理

3.举例说明

QWidget是能够在屏幕上显⽰的⼀切组件的⽗类 QWidget继承⾃QObject,因此也继承了这种对象树关系,⼀个孩⼦⾃动地成为⽗组件的⼀个⼦组件因此,它会显⽰在⽗组件的坐标系统中,被⽗组件的边界剪裁 例如:当⽤⼾关闭⼀个对话框的时候,应⽤程序将其删除,属于这个对话框的按钮、图标等应该⼀起被删除,因为这些都是对话框的⼦组件 当然,也可以⾃⼰删除⼦对象,它们会⾃动从其⽗对象列表中删除 例如:当删除了 ⼀个⼯具栏时,其所在的主窗⼝会⾃动将该⼯具栏从其⼦对象列表中删除,并且⾃动调整屏幕显⽰

4.总结

Qt的对象树机制虽然在⼀定程度上解决了内存问题,但是也引⼊了⼀些值得注意的事情这些细节在开发过程中很可能时不时跳出来烦扰⼀下,所以,最好从开始就养成良好习惯

7.Qt父子对象

一般通过代码来构造界面的时候,通常会把构造界面的代码放到Widget/MainWindow构造函数一般会给当前这个对象设置一个父对象,即将该对象加入到父对象的对象树中Qt中使⽤⽗⼦关系决定该控件"在哪⾥"

8.Qt中乱码的处理

Qt提供了一个qDebug()工具,可以帮助用户自动处理编码方式 正常当作std::cout一样使用即可用法qDebug() << "SnowK";另一个好处:打印的调试日志,是可以通过编译开关统一进行关闭的

9.注意 && 提要

Qt中规定,任何对于GUI上内容的操作必须在主线程中完成 当尝试在⾃⼰的线程中对界⾯元素进⾏修改时,Qt程序往往会直接崩溃这样的约定主要是因为GUI中的状态往往是牵⼀发动全⾝的,修改⼀个地⽅,就需要同步的对其他内容进⾏调整 例如:调整了某个元素的尺⼨,就可能影响到内部的⽂字位置,或者其他元素的位置,这⾥⼀连串的修改,都是需要按照⼀定的顺序来完成的 由于多线程执⾏的顺序⽆法保障,因此Qt从根本上禁⽌了其他线程修改GUI状态,避免后续的⼀系列问题 QByteArray⽤于表⽰⼀个字节数组,可以很⽅便的和QString进⾏相互转换 使⽤QString的构造函数即可把QByteArray转成QString使⽤QStringtoUtf8()即可把QString转成QByteArray

点击全文阅读


本文链接:http://zhangshiyu.com/post/156960.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1