QML中的线程渲染器
Threaded renderer in QML
线程化渲染器在以下代码中不起作用。我使用的是Arch linux-3.14上的Qt 5.4和专有驱动器。
----------mytext.h---------------
#include <QObject>
class Thing : public QObject {
Q_OBJECT
Q_PROPERTY(int qm_no READ qm_no NOTIFY qm_noChanged)
public:
Q_INVOKABLE void loop();
int qm_no();
signals:
void qm_noChanged();
private:
int m_no;
};
----------mytext.cpp---------------
#include "mytext.h"
#include <unistd.h>
int Thing::qm_no() {
return m_no;
}
void Thing::loop() {
while(true) {
m_no += 1;
emit qm_noChanged();
usleep(1000000);
}
}
---------main.cpp----------------
#include <QQmlContext>
#include <QQuickView>
#include <QGuiApplication>
#include <QtQml>
#include "mytext.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Thing myTh;
QQuickView view;
view.rootContext()->setContextProperty("qmyTh",&myTh);
view.setSource(QUrl::fromLocalFile("main.qml"));
view.show();
return app.exec();
}
-------main.qml----------
import QtQuick 2.0;
Rectangle {
id: root
width: 200
height: 200
property var name: "test"
Text {
anchors.fill: parent
text: name
}
MouseArea {
anchors.fill: parent
onClicked: {
qmyTh.loop()
}
}
Connections {
target:qmyTh
onQm_noChanged: {
name = qmyTh.qm_no;
}
}
}
解释::
有一个类Thing
,它的对象是myTh
。类Thing
的函数是提供一个可调用的函数,这里是loop
。然后,此功能将持续更新m_no
值并发出信号。现在的问题是,当无限循环不断更新要显示的值时,我如何更新Text
(name
属性)?
代码对于QML部分(现在)来说是正确的,并且工作正常。不正确的是C++实现。如果删除while
循环,保留其内容,并执行代码,您将看到文本已正确更新。
这种行为的原因应该在Qt quick render
的实现中进行研究。在某些平台上,默认情况下渲染不带线程。我猜你正在使用Windows(请参阅此处的"Qt Quick")。因此,在非线程设置中,通过更新变量然后休眠,您将阻塞整个应用程序,从而阻止gui更新。
您可以使用QTimer
每隔一段时间安排方法执行,也可以出于完全相同的目的设置QML Timer
。
此外,您不需要将新值保存在临时变量中(尤其是var
,它在这种情况下添加了无用的检查)。通过在Text
元素内设置id
,可以直接设置文本属性。这里是重新访问的代码:
import QtQuick 2.0;
Rectangle {
id: root
width: 200
height: 200
Text {
id: myText // the id!
anchors.fill: parent
text: "dummy" // dummy text || left empty || use "qmyTh.qm_no" (ensure a correct value is returned at creation time)
}
MouseArea {
anchors.fill: parent
onClicked: {
qmyTh.loop()
}
}
Connections {
target:qmyTh
onQm_noChanged: myText.text = qmyTh.qm_no // text directly set!
}
}
编辑
似乎使用的渲染是线程化的,因此我的推理不适用。应该还有其他问题。您可以尝试利用调试器并通过在JS处理程序中添加console.info(...)
语句来跟踪问题。搜索问题可能有助于跟踪库中(可能的)错误。
根据你必须运行的后台处理,我仍然认为使用计时器不会那么糟糕。这真的,真的取决于你想要实现什么。然而,如果您想尝试线程,Qt文档中充满了解释(和往常一样)。看看这个,这个而且绝对如此。请注意,"移动"的对象(请参阅链接)不能注册为上下文属性,因此您必须使用其他方法之一来处理QML项目中的线程。
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 最佳做法是从另一个线程访问 qml 中的Q_PROPERTY
- 是否可以在单独的线程中将 QObject 设置为 QML 上下文属性?
- 如何:非根QML前端和根特性的工作人员线程
- 在 c++ 和 qml 中使用多线程
- OpenCV + QML(从另一个线程抓取帧)
- 跨线程从QML调用QObject函数
- QML中的线程渲染器
- 如何从另一个线程的 cpp 代码同步调用 qml 信号处理程序
- Qt 5.1通过线程的QML属性
- 具有多个线程的 QML C++ 属性绑定
- QML是否与多线程/异步调用兼容
- 从运行QML QtQuick2引擎的不同线程更新c++模型的行为