Results 1 to 5 of 5

Thread: SIGSEGV after invoking QML method from c++ thread

  1. #1
    Join Date
    Dec 2016
    Location
    Russia
    Posts
    4
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5

    Default SIGSEGV after invoking QML method from c++ thread

    Hello! I'm trying to write GUI for some console applications and I'm stuck on strange problem...

    In main function:
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QGuiApplication a(argc, argv);
    4.  
    5. QQmlApplicationEngine engine(QUrl::fromLocalFile("test.qml"));
    6.  
    7. Foo fooObject(&engine);
    8.  
    9. QThread thread;
    10. fooObject.moveToThread(&thread);
    11.  
    12. QObject::connect(&thread, SIGNAL(started()), &fooObject, SLOT(start_slot()));
    13.  
    14. thread.start();
    15.  
    16. return a.exec();
    17. }
    To copy to clipboard, switch view to plain text mode 
    In Foo header file:
    Qt Code:
    1. QProcess* testProcess;
    To copy to clipboard, switch view to plain text mode 
    Slot, invoked after thread started:
    Qt Code:
    1. void Foo::start_slot()
    2. {
    3. testProcess = new QProcess;
    4. connect(testProcess, SIGNAL(finished(int)), this, SLOT(finish_slot()));
    5. testProcess->start("uname -a"); //just for example
    6. }
    To copy to clipboard, switch view to plain text mode 
    After completion this slot SIGSEGV occurs:
    Qt Code:
    1. void Foo::finish_slot()
    2. {
    3. delete (testProcess);
    4. QObject* moduleObject = engineObject->rootObjects().first()->findChild<QObject*>("testModule");
    5. QMetaObject::invokeMethod(moduleObject, "test");
    6. }
    To copy to clipboard, switch view to plain text mode 
    But this works fine...
    Qt Code:
    1. void Foo::finish_slot()
    2. {
    3. QObject* moduleObject = engineObject->rootObjects().first()->findChild<QObject*>("testModule");
    4. QMetaObject::invokeMethod(moduleObject, "test");
    5. delete (testProcess);
    6. }
    To copy to clipboard, switch view to plain text mode 

    Is it bug or my mistake? Thanks!
    Last edited by MatrixSan; 10th December 2016 at 14:10.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: SIGSEGV after invoking QML method from c++ thread

    The finish_slot is called from a signal originating from the process and it is usually not a good idea to delete an object while its code is still being executed.

    Best way to delete an object in a slot connected to one of its signals is to call QObject::deleteLater() on the signal sender instead of invoking the delete operator.

    Some other observations:

    1) why the thread?

    2) consider exposing an object to QML instead of retrieving an object from there and invoking its methods: http://doc.qt.io/qt-5/qtqml-cppinteg...ntext-property

    Cheers,
    _

  3. The following user says thank you to anda_skoa for this useful post:

    MatrixSan (11th December 2016)

  4. #3
    Join Date
    Dec 2016
    Location
    Russia
    Posts
    4
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5

    Default Re: SIGSEGV after invoking QML method from c++ thread

    Thank you! Now with deleteLater() all works well!
    I'm using thread, because in project where I ran into this problem with "segfault" there is need to work with data coming from processes and handle them so I thought it's good idea to use threads to prevent GUI freezing. Also there is need to append this data on TextArea on qml side and to block some interface elements during the processes running that is why I decided to invoke qml methods.

  5. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: SIGSEGV after invoking QML method from c++ thread

    Quote Originally Posted by MatrixSan View Post
    I'm using thread, because in project where I ran into this problem with "segfault" there is need to work with data coming from processes and handle them so I thought it's good idea to use threads to prevent GUI freezing.
    QProcess runs asynchronously.
    Unless you need a lot of expensive processing on process data or finish, you are way better of not using threads.

    Quote Originally Posted by MatrixSan View Post
    Also there is need to append this data on TextArea on qml side and to block some interface elements during the processes running that is why I decided to invoke qml methods.
    Both of which can be done way cleaner by letting QML code react to data and changes reported from C++.

    Cheers,
    _

  6. The following user says thank you to anda_skoa for this useful post:

    MatrixSan (12th December 2016)

  7. #5
    Join Date
    Dec 2016
    Location
    Russia
    Posts
    4
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt5

    Default Re: SIGSEGV after invoking QML method from c++ thread

    Thank you very much! I will try to change the architecture of my application.

Similar Threads

  1. Replies: 5
    Last Post: 6th May 2015, 20:37
  2. Invoking a slot from a static method in time
    By Momergil in forum Qt Programming
    Replies: 2
    Last Post: 29th August 2014, 13:51
  3. Call method of Object in different Thread
    By Qiieha in forum Qt Programming
    Replies: 3
    Last Post: 26th July 2012, 14:14
  4. Invoking a slot in another thread
    By dorik in forum Qt Programming
    Replies: 5
    Last Post: 11th July 2011, 19:42
  5. Put in a separate thread a method of a class
    By franco.amato in forum Qt Programming
    Replies: 0
    Last Post: 20th March 2010, 00:45

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.