我是Qt
的新手。我的工作线程是std::thread
。工作线程函数在循环中不断地获取一些数据。数据大小经常在Text
UI上的QML
元素上更新。我有一个监听器回调,它只是一个std::function
,它从thread's function
调用。它向我发送了回调,根据该回调我更新了Text
上的QML
元素。我使用signal slot
机制更新它。
以下是QML : Text
元素:
Text {
id: mytext
objectName: "mytextobject"
function slotUpdateData(someValue){
mytext = someValue
}
}
SignalUpdateData
与位于slotUpdateData
方的QML
相关联。每次我从std::thread
获取数据事件回调时,我emit SignalUpdateData
会更新QML Text element
上的UI
。
void CallBackReceivedFromWorkerThread(float someValue) {
emit SignalUpdateData(someValue)
}
以下是我将此C++ signal
与QML slot
QObject::connect(this, SIGNAL(SignalUpdateData(QVariant)), myTextItemQObject, SLOT(slotUpdateData(QVariant)));
所有这一切都很好。没有崩溃,没有锁定,没有。
根据我的理解,由于工作线程的功能正在触发回调,因此当收到回调时,执行控制在工作线程上。所以当做emit SignalUpdateData(someValue)
时,我们仍然在工作线程上。 据我之前在android
& java
,我们无法在应用程序main thread
之外的任何位置更新用户界面。
所以,这是如何工作的? emit SignalUpdateData(someValue)
将来电置于main UI thread's event loop
吗?尽管Qt
要求main thread
,worker thread
仍在 @font-face {
font-family: ProximaNova;
src: url("../fonts/ProximaNova-Regular.otf") format("opentype");
font-weight: 400;
}
@font-face {
font-family: ProximaNova;
src: url("../fonts/ProximaNova-Semibold.otf") format("opentype");
font-weight: 500;
}
@font-face {
font-family: ProximaNova;
src: url("../fonts/ProximaNova-Bold.otf") format("opentype");
font-weight: bold;
}
@font-face {
font-family: ProximaNova;
src: url("../fonts/ProximaNova-Light.otf") format("opentype");
font-weight: 300;
}
@font-face {
font-family: ProximaNova;
src: url("../fonts/ProximaNova-Thin.otf") format("opentype");
font-weight: lighter;
}
进行用户界面更改吗?如果我的方法很好,那么它是否具有性能影响?这样做的最佳建议是什么?
我想非常肯定这个&让这个工作起来并不幸运。我是否应该使用Qt::Connection_enum以获得最佳方法?
答案 0 :(得分:7)
你正在利用Qt的方式!你不小心碰到了它:这是一个体面设计的标志 - 它“只是有效”。万岁适合你,对Qt万岁:)
这是有效的,因为Qt专门设计用于使其工作,并且您正在使用默认的自动连接,其存在的理由是帮助您解决这一特定情况。所以你碰巧正在做正确的事:不做任何改变!
当您发出信号时,Qt获取相关的源和目标对象互斥锁,并将接收对象的thread()
与QThread::currentThread()
进行比较。如果它们相同,则立即调用插槽/仿函数:它发生在信号体中,因此在信号返回之前调用插槽。这是安全的,因为目标对象是从thread()
使用的,它是安全的。
如果target->thread() != QThread::currentThread()
,则QMetaCallEvent
排队到目标对象。该事件包含(等效的)槽方法指针和槽传递的任何参数的副本。 QObject::event
实现处理事件并执行调用。目标对象线程的事件循环位于调用堆栈上,因为它的作用是将排队事件传递给对象。
以上是Qt::AutoConnection
的含义。如果您使用Qt::QueuedConnection
,则无论线程是什么,第二种情况都适用。如果您使用Qt::DirectConnection
,则无论如何都适用第一种情况。
我的猜测是,在SO上与Qt相关的问题中使用非自动连接类型的95%是不必要的,并且源于缺乏理解和诉诸魔术咒语。