2014-02-28 38 views
2

我有一个类,audio_engine_interface,并在main.cpp中,我将它添加到QML的东西。QThread和QML锁定

viewer.rootContext()->setContextProperty("engine", engine); 

在audio_engine_interface,我有一个audio_engine类,它是计算密集型的,它需要在自己的线程中运行。但是,当我这样做时,整个QML线程锁定了,这意味着我不能暂停(非常重要)。我错过了什么吗?

编辑: 此线程不会搞乱任何东西或从其他地方访问对象。但是,它有一个暂停功能,需要在某个时候调用。对于它的价值,引擎正在进行音高转换。

+0

是的,这里有一个QML特定的机制。否则,GUI线程是GUI线程,并且是唯一可以渲染的线程。 http://qt-project.org/doc/qt-5/qml-qtquick-workerscript.html – user1095108

+0

我使用的是C++,而不是Javascript。 – Jacob

+1

是的,但你可以从javascript调用C++,反之亦然。所以这与你所使用的几乎无关。 – user1095108

回答

1

这是一个问题: -

Qthread thread; 

创建这样一个QThread的对象被创建它在堆栈上。当函数结束时,对象将超出范围并删除QThread对象。

你需要动态地分配在堆上的对象: -

QThread* thread = new QThread; 

然后记得删除线,或将其设置为删除自己: -

//Qt 5 connect syntax 
connect(thread, &QThread::finished, thread, &QThread::deleteLater); 

你也应该知道线程关联性(运行对象的线程)。我建议阅读this article关于如何正确使用QThread。

+0

我正在做这个方法 - 虽然不太清楚deleteLater,我想重用这个线程,或者至少是引擎。并且它不会导致QML在播放时冻结。但是,暂停时,它确实如此。任何指针为什么这可能是? – Jacob

+0

忽略这一点。有一个挥之不去的audio_decoder进程导致它挂断。谢谢您的帮助! – Jacob

+1

没问题。很高兴你得到它排序; O) – TheDarkKnight

1

你有这么多问题。

  1. 当你移动到线程的对象不能有父
  2. 你的线程对象是本地变量,因此它会一天时立即udio_engine_interface::play()末执行
  3. 您直接engine->play();方法调用你,这意味着它将在当前线程中执行。

moveToThread意味着由信号invked槽使用缺省参数第五(Qt::AutoConnection)将在给定线程的事件循环排队连接。

解决它最简单的方法是使用QtConcurrent

void audio_engine_interface::play() 
{ 
    QtConcurrent::run(engine, &EngineClass::play); 
} 

根据你的发动机不会你应该让线程安全的(使用互斥锁的等等),没有细节就很难说,有什么你应该这样做。

+0

如果我这样做,我可以调用引擎 - >暂停()? – Jacob

+0

@MarekR,你可能会对这个关于QtConcurrent和QFuture的主题感兴趣:http://comments.gmane.org/gmane.comp.lib.qt.devel/7942 – TheDarkKnight

+0

我已经看到了,我仍然会使用'QtConcurrent :: run'(其他'QtConcurrent'具有较低的实际价值)。 –