QThread, Qt/C++ and QML UI hanging.



  • I've been trying for a while to get this working, am not being successful in any way. Have tried many different approaches to the issue. Any help with the subject would be appreciated. Example code below causes the UI to hang:

    newthread.h
    @class NewThread : public QThread

    {

    protected:
    void run();
    };
    @

    newthread.cpp
    @
    #include "newthread.h"

    void NewThread::run()
    {
    exec();
    }
    @
    main.cpp

    @
    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    QDeclarativeView view;
    NewThread newThread;
    Control controller;
    QDir dir;
    dir.mkdir("/home/user/MyDocs/.snapIt/");
    view.setViewport(new QGLWidget());
    view.rootContext()->setContextProperty("controller", &controller);
    controller.moveToThread(&newThread);
    newThread.start();
    view.setSource(QUrl("qrc:/qml/main.qml"));
    view.showFullScreen();
    return app.exec();
    }
    @

    One of the functions of control.cpp:

    @void Control::applyDramatic()
    {
    QImage imageDrama(image);
    QImage imageDrama2(imageDrama);
    fmt_filters::image img(imageDrama2.bits(), imageDrama2.width(), imageDrama2.height());
    fmt_filters::blur(img, 10, 10);
    QPainter painter(&imageDrama);
    painter.setCompositionMode(QPainter::CompositionMode_Overlay);
    painter.drawImage(imageDrama.rect(), imageDrama2);
    fmt_filters::contrast(img, 20);
    imageDrama.save("/home/user/MyDocs/.snapIt/snapDrama.jpg", "JPG", 100);
    }
    @

    The issue happens with every single function. Any help would be appreciated.

    Thanks.

    p.s: device is a Nokia N950.



  • Ok, you have an obvject controller which is set the the QDeclarativeView as property.
    How do you call applyDramatic?
    If applyDramatic is a slot and is connected with AutoConnect or with QueuedConnection, it should be handled inside the thread.



  • I have the same problem. I have a logic class which inherits from qobject and is accessible to qml via context properties.
    But after swapping this class to a new thread
    @ QQuickView* v= new QQuickView();
    Logic* adp= new Logic(v);
    QThread* t=new QThread();
    t->start();
    adp->moveToThread(t);
    @
    the gui freezes when i "call" a qml signal wich is connected to the controller slot.

    @onLoginClicked: {
    winlog.connectToDb.connect(logicadapter.connect);//connect to theslot via context props
    connectToDb(name,pw) //emit the qml signal connected to the c++ <- here the gui freeze is caused despite the fact that i swaped it to the other thread
    console.log("JAHAAA User:"+ name + " PW:"+ pw);//<- and that is displayed after return of the "signal"
    }@
    The logic slot calls QThread::sleep --for testing .

    I tried to swap the gui to another thread but that caused a "cant make qobject childs from another thread".

    And when i am running the real connect implementation (which calls a QSQLDb connect) i get a Runtime exception: Application has requested the Runtime to terminate it in an unusual way....
    And the console says ASSERT: "engine->jsStackTop>= mark
    ...only when i swaped the logic to another thread.



  • I managed to get rid of the freezing gui. The trick is to make the signal slot connection in c++, when you have gui and logic in seperat threads.

    The Connections QML element and the someid.signal.connect... thing dont work here and for some reason it seems that both ends in an "Direct Connection" instead of the wanted "Queued Connection.

    => From C++ it works for me ... and be aware to make both direktions in c++
    qml slot < > c++ signal and c++ slot < >qml signal!
    Snippet from my code:
    @QObject* root=dynamic_cast<QObject*>(m_view->rootObject()); // cast needed because of private inharitance + note QQuickItem include is needed
    QObject* obj;
    if(root){
    obj=root->findChild<QObject*>("winlog");
    if(obj){
    qDebug()<<"found winlog and connecting signal";
    QObject::connect(obj,SIGNAL(connectToDb(QString,QString)),this,SLOT(connect(QString,QString)));
    QObject::connect(m_man->getDatabase(),SIGNAL(connectedChanged()),obj,SLOT(onConnectToDbChanged()));
    }else{
    qDebug()<<"didn't found winlog for connecting signal";
    }
    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.