ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – Qt:连接内部构造函数 – 在初始化对象之前是否会调用slot?

2019-08-24 17:09:18  阅读:320  来源: 互联网

标签:c qt event-handling signals-slots


我正在学习Qt框架(C),并想知道QT是否有任何机制来保护插槽在对象完全初始化之前被调用.

考虑A类构造函数:

A::A() {
    mTreeView = new QTreeView();
    ...
    connect(mTreeView, &QTreeView::customContextMenuRequested,
        this, &A::OnContextMenuRequested);
    ...
}

我担心的是用户可以在A的构造函数完成之前右键单击树视图.另一个背景如下:

A::A() {
    mQObj = new MyQObject();
    connect(mQObj, &MyQObject::SomeEvent, this, &A::OnEvent);
}

A::InitB() { mB = new B(); }

A::OnEvent() { mB.doSomething(); }

这里,可以在InitB()运行之前调用doSomething()方法.

我不得不担心这种情况吗?如果是这样,有没有办法避免这些问题,而不必首先初始化所有对象,然后返回并分别连接事件?

解决方法:

在大多数情况下,您不必担心此类情况,因为事件是在同一个线程中传递的.你不得不关心没有“隐藏的多线程”.如果您没有在A的构造函数中显式调用导致事件被处理的函数,那么您将是安全的,并且在处理下一个事件之前,您的当前方法,插槽等的执行已完成.

也就是说,处理新事件并因此执行其他代码(事件处理程序,插槽)的情况是:

>完成当前事件处理程序,插槽等的执行(您创建A的代码),Qt返回事件循环以等待下一个事件.在你的情况下,那是在A实例完全构造之后.
>你启动一个本地事件循环(创建一个QEventLoop对象并调用exec())
>你打电话给QCoreApplication::processEvents()
>你在QDialog上拨打exec()

1)是Qt操作的正常模式:启动app.exec(),启动事件循环.之后的所有内容都由事件(用户输入,计时器,I / O)直接或间接触发.事件发生并添加到事件循环的事件队列中.事件循环调用事件的事件处理程序.事件处理程序完成后,事件循环将选择下一个事件并为其调用处理程序.

所以一切都以有序的方式发生,一个接一个的事件,除非其中一个事件处理程序(比如一个按钮的clicked()信号)执行2,3或4之一.然后Qt处理下一个事件 – 地方,.ie调用exec()或processEvents()的地方.事件处理程序/插槽相应地执行.然后exec()/ processEvents()返回.不幸的是,没有调用exec()/ processEvents()的所有确定性都会消失:用户可能已经做了随机的事情,可以随意更改或删除内容(即使是指针,如果用户关闭了窗口,例).因此,特别是2)和3)容易出错并且通常会导致严重的头痛,所以我会尽可能地避免它们,或者至少要意识到潜在的问题.

现在有你自己使用多线程的情况.由于所有实际的UI和相关的用户事件都是在一个主线程中处理的,因此这里的多线程通常意味着您拥有执行非UI工作的线程,并通过调用UI线程中的对象上的函数与UI线程进行交互,修改数据由两个线程共享,或使用跨线程信号/插槽连接.

>如果您不使用信号/插槽但是从辅助线程到UI线程的直接方法调用或修改共享数据,通常的多线程规则适用:除非您知道自己在做什么并相应地使用同步,否则事情将发生严重错误. Qt的UI类不是线程安全的.
>如果您使用信号/插槽,则呼叫是/排队/,即如果线程B发出信号并且您在主线程的插槽中接收到该信号,则插槽的呼叫将以与用户事件相同的方式传递:适用与用户事件相同的规则.除非您执行2,3,4之一,否则在事件处理程序/槽返回之前不会调用插槽.因此,跨线程信号/插槽连接是消息传递的方式/消息通过事件循环传递的方式.

标签:c,qt,event-handling,signals-slots
来源: https://codeday.me/bug/20190824/1709916.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有