Cod*_*rus 3 c++ qt event-handling signals-slots
我正在学习Qt框架(C++),并想知道QT是否有任何机制来保护插槽在对象完全初始化之前被调用.
考虑A类构造函数:
A::A() {
mTreeView = new QTreeView();
...
connect(mTreeView, &QTreeView::customContextMenuRequested,
this, &A::OnContextMenuRequested);
...
}
Run Code Online (Sandbox Code Playgroud)
我担心的是用户可以在A的构造函数完成之前右键单击树视图.另一个背景如下:
A::A() {
mQObj = new MyQObject();
connect(mQObj, &MyQObject::SomeEvent, this, &A::OnEvent);
}
A::InitB() { mB = new B(); }
A::OnEvent() { mB.doSomething(); }
Run Code Online (Sandbox Code Playgroud)
这里,可以在InitB()运行之前调用doSomething()方法.
我不得不担心这种情况吗?如果是这样,有没有办法避免这些问题,而不必首先初始化所有对象,然后返回并分别连接事件?
在大多数情况下,您不必担心此类情况,因为事件是在同一个线程中传递的.你不得不关心没有"隐藏的多线程".如果您没有在A的构造函数中显式调用导致事件被处理的函数,那么您将是安全的,并且在处理下一个事件之前,您的当前方法,插槽等的执行已完成.
也就是说,处理新事件并因此执行其他代码(事件处理程序,插槽)的情况是:
A
),Qt返回事件循环以等待下一个事件.在你的情况下,那是在A实例完全构造之后.1)是Qt操作的正常模式:启动app.exec(),启动事件循环.之后的所有内容都由事件(用户输入,计时器,I/O)直接或间接触发.事件发生并添加到事件循环的事件队列中.事件循环调用事件的事件处理程序.事件处理程序完成后,事件循环将选择下一个事件并为其调用处理程序.
所以一切都以有序的方式发生,一个接一个的事件,除非其中一个事件处理程序(比如一个按钮的clicked()信号)执行2,3或4之一.然后Qt处理下一个事件- place,.ie调用exec()或processEvents()的地方.事件处理程序/插槽相应地执行.然后 exec()/ processEvents()返回.现在,不用调用exec()/ processEvents()的所有确定性都会消失:不幸的是:用户可能已经做了随机的事情,可以随意更改或删除的东西(甚至this
指针,如果用户关闭窗口,例如).因此,特别是2)和3)容易出错并且通常会导致严重的头痛,因此我会尽可能避免使用它们,或者至少要注意潜在的问题.
现在有你自己使用多线程的情况.由于所有实际的UI和相关的用户事件都在一个主线程中处理,这里的多线程通常意味着你有线程做非UI工作,并通过调用UI线程中的对象上的函数与UI线程交互,修改数据由两个线程共享,或使用跨线程信号/插槽连接.