gpt4 book ai didi

c++ - 默认情况下,从工作线程发出 Qt::signal 会使 UI 在主线程上更新?

转载 作者:太空宇宙 更新时间:2023-11-03 10:40:18 25 4
gpt4 key购买 nike

我是 Qt 的新手。我有一个 std::thread 工作线程。工作线程函数在循环中不断获取一些数据。 QML UI 上的 Text 元素的数据大小经常更新。我有一个监听器回调,它只是一个 std::function,它是从 线程的函数 调用的。它向我发送回调,我根据这些回调更新了 QML 上的 Text 元素。我使用 signal slot 机制更新它。

以下是 QML : Text 元素:

Text {
id: mytext
objectName: "mytextobject"

function slotUpdateData(someValue){
mytext = someValue
}
}

SignalUpdateData 与驻留在 QML 端的 slotUpdateData 相连。每次我从 std::thread 获取数据事件回调时,我都会发出 SignalUpdateData,它会更新 UI 上的 QML Text element

void CallBackReceivedFromWorkerThread(float someValue) {
emit SignalUpdateData(someValue)
}

以下是我如何将此C++ 信号QML 插槽 连接

QObject::connect(this, SIGNAL(SignalUpdateData(QVariant)), myTextItemQObject, SLOT(slotUpdateData(QVariant)));

所有这一切都很好。没有崩溃、锁定,什么都没有。

根据我的理解,由于工作线程的函数正在触发回调,因此当收到回调时,执行控制权在工作线程上。因此,当执行 emit SignalUpdateData(someValue) 时,我们仍在工作线程中。 据我以前在 androidjava 中的经验,我们无法从 主线程 之外的任何地方更新 UI应用程序。

那么,这是如何运作的? emit SignalUpdateData(someValue) 是否将调用放入主 UI 线程的事件循环?尽管我从 worker thread 调用它,Qt 是否仍在 main thread 上更改 UI?如果我的方法没问题,那么它对性能有影响吗?执行此操作的最佳建议是什么?

我想对此非常确定,而不仅仅是幸运地让它发挥作用。我应该使用 Qt::Connection_enum 吗?以及最佳方法?

最佳答案

您正在以其应有的方式利用 Qt!你不小心遇到了它:这是一个体面设计的标志 - 它“正常工作”。你万岁,Qt 万岁:)

它之所以有效,是因为 Qt 是专门为使其有效而设计的,并且您正在使用默认的自动连接,其存在的理由就是在这种特定情况下帮助您解决问题。所以你恰好做对了一切:什么都不改变!

当您发出信号时,Qt 获取相关的源和目标对象互斥锁,并将接收对象的 thread()QThread::currentThread() 进行比较。如果它们相同,槽/仿函数会立即被调用:它发生在信号体中,所以槽会在信号返回之前被调用。这是安全的,因为目标对象是从其安全的 thread() 中使用的。

如果 target->thread() != QThread::currentThread(),则 QMetaCallEvent 将排队到目标对象。该事件包含(等效的)插槽方法指针和插槽传递的任何参数的拷贝。 QObject::event 实现处理事件并执行调用。目标对象线程的事件循环位于调用堆栈上,因为它的工作是将排队的事件传递给对象。

以上就是一个Qt::AutoConnection的简单意思。如果您使用的是 Qt::QueuedConnection,则无论线程是什么,第二种情况都适用。如果您使用的是 Qt::DirectConnection,第一种情况无论如何都适用。

我的猜测是,在 SO 上与 Qt 相关的问题中,>95% 的非自动连接类型的使用是不必要的,并且源于缺乏理解和求助于魔法咒语。

关于c++ - 默认情况下,从工作线程发出 Qt::signal 会使 UI 在主线程上更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40728341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com