当前位置:   article > 正文

Qt知识点总结_qt知识分享

qt知识分享

一、Qt 三大核心机制

1、信号槽

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

2、元对象系统 ???

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

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

3、事件模型

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

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

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

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

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

信号与槽的具体流程。

  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的博客-CSDN博客

九、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的博客-CSDN博客

Qt消息机制:事件分发和事件过滤_qt 消息过滤_SOC罗三炮的博客-CSDN博客

Qt中父子widget的事件传递_imxiangzi的博客-CSDN博客

十、为什么 new QWidget 不需要 delete

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

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

十一、事件与信号的区别

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

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

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

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

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

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

十二、Qt 实现多线程

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

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

Qt实现多线程编程的两种方式_qt多线程_觉皇嵌入式的博客-CSDN博客

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

十三、QT 保证多线程安全

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

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

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

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

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

十六、参考内容

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

06_qt基础开发的常见面试题和解答_精一思维的博客-CSDN博客

QT 面试题汇总_qt面试题_BC菜鸟的博客-CSDN博客

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/601110
推荐阅读
相关标签
  

闽ICP备14008679号