c++ - Qt 5.1 QML property through Threads -
for purpose of resolution, i've created testapp repeat same problem have.
i'm porting software qt 4.8 qt 5.1.
my first program multithreaded, , working smoothly qml, provided classes thread safe. message :
qobject::connect: no such slot testapp::run() in ..\threadingtest\main.cpp:21 qqmlengine: illegal attempt connect testapp(0x29cfb8) in different thread qml engine qqmlengine(0x2f3e0f8).
this code reproduce error :
main.cpp :
#include <qtgui/qguiapplication> #include <qqmlcontext> #include <qthread> #include "qtquick2applicationviewer.h" #include "testapp.h" int main(int argc, char *argv[]) { int out; qguiapplication app(argc, argv); qtquick2applicationviewer viewer; testapp * testapp = new testapp(); qthread * testappthread; testappthread = new qthread(); qobject::connect(testappthread, signal(started()), testapp, slot(run())); testapp->movetothread(testappthread); testappthread->start(); viewer.rootcontext()->setcontextproperty("testapp", testapp); viewer.setmainqmlfile(qstringliteral("qml/threadingtest/main.qml")); viewer.showexpanded(); out = app.exec(); testappthread->quit(); testappthread->wait(); delete testapp; delete testappthread; return out; }
testapp.h :
#ifndef testapp_h #define testapp_h #include <qobject> #include <qstring> #include <qtimer> #include <qreadwritelock> #define helloworld "hello world !" extern qreadwritelock helloworldlock; class testapp : public qobject { q_object q_property(qstring helloworld read gethelloworld write sethelloworld notify helloworldchanged) public: explicit testapp(qobject *parent = 0); virtual ~testapp(); qstring gethelloworld(); void sethelloworld(qstring); public slots: void run(); void togglehelloworld(); signals: void helloworldchanged(); private: qstring m_helloworld; qtimer * m_timer; }; #endif // testapp_h
testapp.cpp :
#include "testapp.h" qreadwritelock helloworldlock(qreadwritelock::recursive); testapp::testapp(qobject *parent) : qobject(parent) { helloworldlock.lockforwrite(); m_helloworld = helloworld; helloworldlock.unlock(); m_timer = new qtimer(this); connect(m_timer, signal(timeout()), this, slot(togglehelloworld())); } testapp::~testapp() { m_timer->stop(); delete m_timer; } qstring testapp::gethelloworld() { helloworldlock.lockforread(); qstring out = m_helloworld; helloworldlock.unlock(); return out; } void testapp::sethelloworld(qstring text) { helloworldlock.lockforwrite(); m_helloworld = text; helloworldlock.unlock(); emit helloworldchanged(); } void testapp::run() { m_timer->start(1000); } void testapp::togglehelloworld() { helloworldlock.lockforwrite(); if(m_helloworld == "") { m_helloworld = helloworld; } else { m_helloworld = ""; } helloworldlock.unlock(); emit helloworldchanged(); }
main.qml :
import qtquick 2.0 rectangle { width: 360 height: 360 text { text: testapp.helloworld anchors.centerin: parent } mousearea { anchors.fill: parent onclicked: { qt.quit(); } } }
my program quite complex (a lot of properties , classes share interface) , wouldn't have create interface class connect properties... have suggestions cope issue ?
you don't need thread app cause in qt5, qml 2 engine massively multithreaded, launch qquickview, expose c++ parts need context, set qml file in it, , show(). it's sufficient. don't try modify qml thread yourself, more complex in qml1.
Comments
Post a Comment