Qt知识点总结_qt知识分享-程序员宅基地

技术标签: Qt  qt  开发语言  

一、Qt 三大核心机制

1、信号槽

connect(信号发出者,信号,信号接收者,槽,连接方式(隐藏默认自动连接))//五个参数

2、元对象系统 ???

元对象系统分为三大类:QObject类、Q_OBJECT宏和元对象编译器moc

Qt的类包含Q_OBJECT宏 moc编译器会对该类编译成标准的C++代码

3、事件模型

事件发射器:把事件插入到事件队列;

事件队列:顾名思义,不解释;

事件循环:是一个无限循环,用于从事件队列上获取事件,然后交给对应的事件处理函数处理;

事件处理函数:响应某个事件而调用的函数,比如发生鼠标左键点击事件,应用程序该执行什么样的动作进行响应,这些动作就是在事件处理函数中定义的。
Qt 三大核心机制_qt 机制_tomorrow778的博客-程序员宅基地

二、信号与槽机制原理???

信号与槽的具体流程。

  1. moc查找头文件中的signals,slots,标记出信号和槽。
  2. 将信号槽信息存储到类静态变量staticMetaObject中,并且按声明顺序进行存放,建立索引。
  3. 当发现有connect连接时,将信号槽的索引信息放到一个map中,彼此配对。
  4. 当调用emit时,调用信号函数,并且传递发送信号的对象指针,元对象指针,信号索引,参数列表到active函数
  5. 通过active函数找到在map中找到所有与信号对应的槽索引
  6. 根据槽索引找到槽函数,执行槽函数。 

三、自定义信号槽注意事项:

(1)发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);

(2)使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;

(3)槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;

(4)使用 emit 在恰当的位置发送信号;

(5)使用QObject::connect()函数连接信号和槽;

(6)任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数。

四、讲述Qt信号槽机制与优势与不足

优点:

①类型安全。需要关联的信号槽的签名必须是等同的。即信号的参数类型和参数个数同接受该信号的槽的参数类型和参数个数相同。若信号和槽签名不一致,编译器会报错。

②松散耦合。信号和槽机制减弱了Qt对象的耦合度。激发信号的Qt对象无需知道是那个对象的那个信号槽接收它发出的信号,它只需在适当的时间发送适当的信号即可,而不需要关心是否被接受和那个对象接受了。Qt就保证了适当的槽得到了调用,即使关联的对象在运行时被删除。程序也不会奔溃。

③灵活性。一个信号可以关联多个槽,或多个信号关联同一个槽。

不足:速度较慢。与回调函数相比,信号和槽机制运行速度比直接调用非虚函数慢10倍。
 

五、Qt信号和槽的本质是什么

回调函数。信号或是传递值,或是传递动作变化;槽函数响应信号或是接收值,或者根据动作变化来做出对应操作。

六、信号与槽与函数指针的比较

  1. 回调函数使用函数指针来实现的,如果多个类都关注一个类的动态变化,这样就会需要写出一个比较长的列表来管理这些类之间的关系。稍微在编码方面不那么灵活,稍显冗余。
  2. QT使用信号与槽来解决这个连接问题,这种方式比较清晰简单一些,一个类只需要清楚自己有几个槽函数有几个信号,然后将信号与槽进行连接,QT会自己处理函数的调用关系。这样在软件设计角度更加的清晰,灵活,不容易出错。 3.Qt信号与槽机制降低了Qt对象的耦合度。发信号的对象不需要知道有几个槽函数,也不需要关系是否收到信号,或者谁收到了,谁没收到。同样的槽函数也不需要知道谁是信号的发出者。信号只需要在合适的时机发出即可,降低了对象之间的耦合度。

七、信号与槽的多种用法

(1)一个信号可以和多个槽相连

如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。

(2)多个信号可以连接到一个槽

只要任意一个信号发出,这个槽就会被调用。

(3)一个信号可以连接到另外的一个信号

当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。

(4)槽可以被取消链接

这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。

(5)使用Lambda 表达式

在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的。

八、Qt connect 函数的连接方式

  1. Qt::AutoConnection: 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。
  2. Qt::DirectConnection:槽函数会在信号发送的时候直接被调用,槽函数和信号发送者在同一线程。效果看上去就像是直接在信号发送位置调用了槽函数,效果上看起来像函数调用,同步执行。 emit语句后面的代码将在与信号关联的所有槽函数执行完毕后才被执行。
  3. Qt::QueuedConnection:信号发出后,信号会暂时被放到一个消息队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,然后执行和信号关联的槽函数,这种方式既可以在同一线程内传递消息也可以跨线程操作。 emit语句后的代码将在发出信号后立即被执行,无需等待槽函数执行完毕
  4. Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。而且接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
  5. Qt::UniqueConnection:这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是为了避免重复连接。

QT信号与槽的连接后槽函数执行方式_槽函数中断执行_zichenla的博客-程序员宅基地

九、Qt 的事件过滤器

  1. 父窗口类通过重写eventFilter方法来监听子控件的相关事件进行处理。 使用这种方式的好处是不需要通过重写控件的方式获取某些事件,对于安装了事件过滤器的对象,他们所有的事件都会经过这个事件过滤器,所以就可以直接在父窗口中进行监测。
  2. 专门的事件过滤器类,对特定的对象/特定的事件进行处理。 事件过滤器类只需对当前安装的对象进行处理,无需关心其他操作,且一个事件过滤器类可以被多个对象使用。
  3. 给QApplication安装事件过滤器,达到全局事件监听的效果。 在notify方法下发事件的时候,QApplication对象可以拿到第一控制权,对某些事件优先进行处理,比如全局的快捷键操作。

注意点:

  1. 事件过滤器可以安装在任何继承QObject的对象上,也可以安装在QApplication对象上(全局事件过滤器);
  2. 事件过滤器(eventFilter方法)返回值为true,表示将当前事件进行过滤,不会发送到对象本身;如果返回false,表示对当前事件不做任何处理,会通过event()方法将事件分发给父窗口部件。如果不知道怎么处理或者返回什么,那就返回父类的eventFilter方法(类似 return QObject::eventFilter(watched, event));
  3. 一个对象可以安装多个事件过滤器(也就是一个对象的事件可以被多个对象进行监控/处理/过滤), 并且最先安装的事件过滤器是最后被调用的,类似于栈的操作,先进后出;
  4. 一个事件过滤器可以被多个对象安装,但是如果在事件过滤器(eventFilter方法)中把该对象删除了, 一定要将返回值设为true。否则 Qt会将事件继续分发给这个对象,从而导致程序崩溃。

在Qt中,按下一个按键后,事件的传递过程通常涉及以下步骤:

  1. 操作系统将按键事件发送到应用程序的事件队列中。
  2. Qt的事件循环从事件队列中取出按键事件。
  3. 事件循环将按键事件发送到应用程序的事件过滤器中进行处理。如果应用程序设置了事件过滤器,则可以在事件到达目标对象之前拦截和修改事件。
  4. 如果事件未被过滤器拦截,则事件循环将事件发送到目标对象。目标对象是接收事件的对象,通常是用户界面中的控件,比如按钮或文本框。
  5. 目标对象根据事件类型执行相应的操作,比如文本框可能将输入字符添加到文本中,按钮可能触发一个信号。
  6. 如果目标对象未处理事件,则事件将被发送到目标对象的父对象,直到事件被处理或到达应用程序的根对象为止。
  7. 如果事件到达应用程序的根对象仍未被处理,则事件将被忽略或丢弃。

关于eventFilter的返回值?

返回基类的event(QEvent*)和返回false的区别在于事件的处理方式。返回false会让事件继续按照标准的事件传递过程进行传递,而返回基类的event(QEvent*)会让事件绕过标准的事件传递过程,交给QAbstractNativeEventFilter的eventFilter函数进行处理。如果事件需要进行标准的事件处理流程,则应该返回false。如果事件需要进行特殊的处理方式,则可以考虑返回基类的event(QEvent*)并在eventFilter函数中进行相应的处理。

Qt 事件处理和事件过滤器的返回值_weixin_30596165的博客-程序员宅基地

Qt消息机制:事件分发和事件过滤_qt 消息过滤_SOC罗三炮的博客-程序员宅基地

Qt中父子widget的事件传递_imxiangzi的博客-程序员宅基地

十、为什么 new QWidget 不需要 delete

QT的父子对象机制(对象树机制)是在 QWidget和QOject中实现的。当我们使用父对象来创建一个对象的时候 ,父对象会把这个 对象添加到自己的子对象列表中。当这个父对象被删除的时候,它会遍历它的子对象类表并且删除每一个子对象,然后子对象们自己再删除它们自己的子对象,这样递归调用直到所有对象都被删除。
这种父子对象机制会在很大程度上简化我们的内存管理工作,减少内存泄露的风险。我们需要显式地删除(就是用delete)的对象是那些使用new创建的并且没有父对象的对象。如果我们在删除一个对象的父对象之前删除它,QT会自动地从它的父对象的子对象列表中移除它的。
Qt 之 new对象何时销毁_qt判断new的对象已被销毁_wjjontheway的博客-程序员宅基地

在 Qt 中,当一个父对象被删除时,它会自动删除它所有的子对象,包括 QWidget 对象和其他对象。在删除父对象时,Qt 会先遍历它的子对象列表,递归删除每个子对象,然后再删除父对象本身。因此,先删除子对象,再删除父对象。

十一、事件与信号的区别

作用对象:
信号可以从一个对象发送到任何关注该信号的对象。
事件则只能发送到特定的对象。

传递数据:
信号可以携带任意用户定义的数据。
事件只能携带预定义的数据。

顺序:
信号是同步的,即发送方发送信号,接收方立即接收(同一个线程)。
事件是异步的,事件在事件队列中等待处理。

使用场景:
信号用于对象间通信,通知其他对象状态的变化。
事件用于处理系统事件,如鼠标、键盘等输入事件。

实现:
信号是信号与槽机制的内容。
事件是基于QEvent类实现的。

优点:
信号提供更高效和方便的对象间通信。
事件可以在事件队列中处理,不会阻塞GUI。

十二、Qt 实现多线程

方法一:①创建一个类从QThread类派生②在子线程类中重写 run 函数, 将处理操作写入该函数中 ③在主线程中创建子线程对象, 启动子线程, 调用start()函数

方法二:①将业务处理抽象成一个业务类, 在该类中创建一个业务处理函数②在主线程中创建一QThread类对象 ③在主线程中创建一个业务类对象 ④将业务类对象移动到子线程中 ⑤在主线程中启动子线程 ⑥通过信号槽的方式, 执行业务类中的业务处理函数

Qt实现多线程编程的两种方式_qt多线程_觉皇嵌入式的博客-程序员宅基地

多线程使用注意事项: 
1. 业务对象, 构造的时候不能指定父对象 
2. 子线程中只能处理一些数据相关的操作, 不能涉及窗口
 

十三、QT 保证多线程安全

QT提供了一些机制来保证线程安全,如互斥量(QMutex)、信号量(QSemaphore)和读写锁(QReadWriteLock)。这些机制可以在多线程环境下实现数据的同步访问和线程间的协调。

十四、在QT中,如何处理用户输入和事件响应?

QT提供了事件处理机制来处理用户输入和事件响应。通过重写事件处理函数(如keyPressEvent、mousePressEvent等),可以捕获用户输入的事件并作出相应的响应。此外,还可以使用信号与槽机制来捕获和响应特定的用户行为,比如按钮点击、鼠标滚轮等。

十五、如何进行界面设计和布局,在QT中有哪些常用的布局方式?

示例回答:在QT中,可以使用布局管理器来帮助进行界面设计和布局。常用的布局方式包括水平布局(QHBoxLayout)、垂直布局(QVBoxLayout)、网格布局(QGridLayout)等。布局管理器可以根据窗口大小自动调整控件的位置和大小,保证界面在不同分辨率下具有良好的显示效果。
 

十六、参考内容

Qt 常用面试题整理(不定时整理)_牛客网

06_qt基础开发的常见面试题和解答_精一思维的博客-程序员宅基地

QT 面试题汇总_qt面试题_BC菜鸟的博客-程序员宅基地

 https://www.cnblogs.com/FKdelphi/p/12867341.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41709234/article/details/131366981

智能推荐

ABBYY2024免费永久版OCR图片文字识别软件_orc识别软件-程序员宅基地

文章浏览阅读316次,点赞3次,收藏10次。总体来说,ABBYY FineReader 15是一款功能强大、易于使用的OCR图片文字识别软件,适合个人和企业用户在多种场景下使用。然而,用户也需要考虑其价格和资源消耗等因素是否适合自己的需求。_orc识别软件

使用SBM-DEA模型优化绩效评估:理论、案例与MATLAB实践-程序员宅基地

文章浏览阅读1.9k次。数据包络分析是一种非参数方法,用于评估各种类型的决策单元,如企业、医院、学校等。其核心思想是将各个决策单元的输入和输出转化为一个效率评分,以比较它们的相对绩效。DEA的主要应用领域包括绩效评估、资源分配、效率改进等。_sbm-dea

计算机应用模块数量如何填写,职称计算机考试科目、模块数量介绍-程序员宅基地

文章浏览阅读1.7k次。原标题:职称计算机考试科目、模块数量介绍全国计算机应用能力考试坚持"实事求是,区别对待,逐步提高"的原则,不同地区、不同部门根据本地区、本部门的实际情况,确定适合本地区、本部门的考试范围要求。1、不同地区和部门自主确定应考科目数量在对专业技术人员计算机应用能力的具体要求上,各省、自治区、直辖市人事厅(局)和国务院有关部门干部(人事)部门应结合本地区、本部门的实际情况,确定本地区、本部门在评聘专业技..._模块数

设计一个 shell 程序,添加一个新组为 class1,然后添加属于这个组的 30 个用户,用户名的形式为 stdxx ,其中 xx 从 01 到 30_设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的-程序员宅基地

文章浏览阅读5.5k次,点赞3次,收藏49次。Linux例题:设计一个 shell 程序,添加一个新组为 class1,然后添加属于这个组的 30 个用户,用户名的形式为 stdxx ,其中 xx 从 01 到 30_设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的

基于51单片机的冰箱温度控制除霜系统Proteus仿真-程序员宅基地

文章浏览阅读481次,点赞24次,收藏12次。AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectronics)公司生产的一系列单片机之一。它基于8051内核,并具有许多与其兼容的特性。主要特点如下:内部存储器:具有8KB的闪存(Flash)存储器,可用于存储用户程序和数据。这些存储器的内容可以通过编程器进行编程和擦除。RAM存储器:配备了256字节的随机存取存储器(RAM),用于暂存数据和程序的变量。

动身吧褪色者,即使引导已经破碎,也请您当上艾尔登之王-程序员宅基地

文章浏览阅读202次。我的第一篇博客,也祝所有学习计算机的兄弟们,前程似锦!

随便推点

Linux学习教程,Linux入门教程(超详细)| 网址推荐_linux中大量使用脚本语言,而不是c语言!-程序员宅基地

文章浏览阅读1.3k次,点赞2次,收藏51次。1Linux简介2Linux安装3Linux文件和目录管理4Linux打包(归档)和压缩5Vim文本编辑器6Linux文本处理(Linux三剑客)7Linux软件安装8Linux用户和用户组管理9Linux权限管理10Linux文件系统管理11Linux高级文件系统管理12Linux系统管理13Linux备份与恢复14Linux系统服务管理15Linux系统日志管理16Linux启动管理17LAMP环境搭建和LNMP环境搭建18SEL..._linux中大量使用脚本语言,而不是c语言!

c语言函数base,c中base的用法-程序员宅基地

文章浏览阅读1.7k次。c中base的用法的用法你知道吗?下面小编就跟你们详细介绍下c中base的用法的用法,希望对你们有用。c中base的用法的用法如下:1、调用基类中的重名方法[csharp]public class Person{protected string ssn = "444-55-6666";protected string name = "John L. Malgraine";public virtua..._c语言中base=16是什么意思

为什么接口中变量要用final修饰_接口参数都定义为final的作用-程序员宅基地

文章浏览阅读6.7k次,点赞3次,收藏7次。今天碰到这个问题时候,还真不好理解,只知道interface中的变量默认是被public static final 修饰的,接口中的方法是被public和abstrct修饰的。查阅了很多资料,做了些例子,得出以下结论,不足的地方希望大家指出。 Java代码 /* * 关于抽象类和接口 * * 1_接口参数都定义为final的作用

【R语言学习笔记】6、List列表详解_r语言怎么查看list有几个项目-程序员宅基地

文章浏览阅读4.4k次,点赞3次,收藏25次。创建一个list列表> mylist <- list(stud.id = 1234,+ stud.name = "Tom",+ stud.marks = c(12, 3, 14, 25, 19))> mylist$stud.id[1] 1234$stud.name[1] "Tom"$stud.marks[1] 12 3 14 25 19取列表的值注..._r语言怎么查看list有几个项目

java 判断标点符号_Java判断中英文符号、标点的实现-程序员宅基地

文章浏览阅读2.7k次。本文介绍了Java判断中英文符号、标点的实现,分享给大家,具体如下:方法一、用unicodeBlock和unicodeScript判断在Java中,主要使用 Character类处理字符有关功能,而JDK 1.7中Character是按照Unicode 6.0版本实现的,所以这个要先学习下常用的 Unicode编码。其中的UnicodeBlock 和 UnicodeScript类可以帮助我们判断字..._java 判断字符是标点符号

图像缩放算法-程序员宅基地

文章浏览阅读2.1k次。怎样计算缩放比例?有四种方法:1.对角线法,以对角线长度为准,其伸长者为放大,缩短者为缩小,其底边并行线即为新尺寸。2.计算器法,先输入欲缩放宽度,按除键,再输入原稿尺寸,再按%即得。3.比例尺法,将比例尺上方设定原稿宽度,与比例尺下方新尺寸对齐,即可直接找出缩放百分比。4.公式法,套入(原稿宽度/原稿高度═新宽度/新..._图像缩放算法