Results 1 to 12 of 12

Thread: Qt/Qml + RTI DDS Application

  1. #1
    Join Date
    Apr 2014
    Posts
    6
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Qt/Qml + RTI DDS Application

    Hi,

    I'm currently making a small application using QtCreator where I use RTI DDS to implement some simple request/reply communications.
    By clicking on a simple button from a qml designed GUI, I'd like to send a request using a RTI DDS "requester" and then receiving and displaying the reply by using a RTI DDS "replier".

    So I created my DDS requester and replier classes, both unheriting from QObject, and made the link with the qml part using setContextProperty.

    My problem now is that I'm not very sure what is the right way of using QThreads to launch in paralel both the requester and the replier in a proper way.

    What I did for now, which seems to be half working and not very proper is :

    In my main :

    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QGuiApplication app(argc, argv);
    4. QtQuick2ApplicationViewer viewer;
    5.  
    6. requester req;
    7. replier rep;
    8.  
    9. QThread requesterThread;
    10. QThread replierThread;
    11.  
    12. req.moveToThread(&requesterThread);
    13. rep.moveToThread(&replierThread);
    14.  
    15. req.connect(&requesterThread, SIGNAL(started()), SLOT(runReq())); //where runReq() is the main method of my requester class
    16. rep.connect(&replierThread, SIGNAL(started()), SLOT(runRep()));
    17.  
    18. req.connect(&requesterThread,SIGNAL(finished()),SLOT(deleteLater()));
    19. rep.connect(&replierThread,SIGNAL(finished()),SLOT(deleteLater()));
    20.  
    21. &requesterThread.connect(&requesterThread,SIGNAL(finished()),SLOT(deleteLater()));
    22. &replierThread.connect(&replierThread,SIGNAL(finished()),SLOT(deleteLater()));
    23.  
    24.  
    25. //Setting context properties
    26. viewer.rootContext()->setContextProperty("requester",&req );
    27. viewer.rootContext()->setContextProperty("replier", &rep);
    28.  
    29. viewer.rootContext()->setContextProperty("requesterTHREAD",&requesterThread );
    30. viewer.rootContext()->setContextProperty("replierTHREAD", &replierThread);
    31.  
    32.  
    33. viewer.setMainQmlFile(QStringLiteral("qml/ProjectUsecase1/main.qml"));
    34. viewer.showExpanded();
    35.  
    36. return app.exec();
    To copy to clipboard, switch view to plain text mode 


    And then I call : requesterThread.start() and replierThread.start() in my main.qml when the button is clicked.

    So, I'm pretty sure there's a better way to create and destroy the threads, anywhere but in the main.cpp. Should I create a class dedicated to the management of my threads ? What's the cleaniest way to destroy the threads after the requester's and replier's execution ?

    Thank you very much by advance.

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

    Default Re: Qt/Qml + RTI DDS Application

    Are requester::runReq() and replier::runRep blocking?

    I.e. what is the reason you are using threads?

    Cheers,
    _

  3. #3
    Join Date
    Apr 2014
    Posts
    6
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt/Qml + RTI DDS Application

    Hello, yes, the runReq() function blocks until it receives a reply and the runRep() blocks until it receives a request.

    With a similar project under Visual Studio, I gotta open both the requester.exe an the replier.exe in different cmd prompts to enable the communication between them.
    With my Qt project I'd like to launch them and make them communicate with a simple click from my GUI, that's why I thought using threads was the only way, if it's not I'm opened to any suggestions

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

    Default Re: Qt/Qml + RTI DDS Application

    I was mainly asking because the use of the moveToThread() approach suggests that the thread should use its default event loop.

    Is the UI just triggering the start of the operations or is it somehow getting values back at some point?

    Cheers,
    _

  5. #5
    Join Date
    Apr 2014
    Posts
    6
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt/Qml + RTI DDS Application

    The UI shall display the results, so yes, the result of the request is theorically able to be available by the qml side thanks to setContextProperty(). However I notices that my UI isnt refreshing dynamically once the result is available, I read somewhere that I shall use QAbstractItemModel instead of setContextProperty().

    As far as the threads are concerned, despite my use of the connect() method with the deleteLater() in the main.cpp, they don't seem to end properly and that's what is bothering me

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,418
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt/Qml + RTI DDS Application

    A model would most likely also be exposed as a context property, it really depends on how your result is created and how it is communicated to the QML scene.

    How do you currently do that?

    Cheers,
    _

    P.S.: Your connect finished->deleteLater is never triggered, since the threads are not told to quit.

  7. #7
    Join Date
    Apr 2014
    Posts
    6
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt/Qml + RTI DDS Application

    The result is generated by the DDS replier, then it is sent back to the DDS requester. When I receive it, I copy the value in a m_reqResult var, which is accessible from qml thanks to the setContextProperty() and the line :

    Qt Code:
    1. Q_PROPERTY(int m_reqResult READ getResult WRITE setResult NOTIFY resultChanged)
    To copy to clipboard, switch view to plain text mode 
    in my requester class.

    For the threads, should I emit a finished() signal in the end of my runReq() and runRep() functions ?

    Thanks a lot

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

    Default Re: Qt/Qml + RTI DDS Application

    Since your thread payload is "run once" and blocking it is probably cleaner to reimplement QThread::run() instead of "abusing" a thread with event loop, but yes, emitting signal at the end of the payload function should work as well.

    Cheers,
    _

  9. #9
    Join Date
    Apr 2014
    Posts
    6
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt/Qml + RTI DDS Application

    Ok so you're saying that instead of making the slot runReq() do the work I should transfer this work to the QThread::run() function which I can call since my requester class inherits from QObject, right ?

    Thanks

  10. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,418
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt/Qml + RTI DDS Application

    I am not quite sure I understand the question.

    QThread::run() is executed by the new thread, its context is a lot like main().

    The only thing you need to be careful about is creating QObjects in different thread contexts. If you create a QObject in a secondary thread you either destroy it before the thread ends or you move it to another thread, e.g. the application's main thread.

    If you protect your property getters and setters with mutexes you can have a QObject in a secondary thread and use it from QML.
    You can alternatively have the interface object live in the main thread and implement some of its methods in a way that they delegete to a thread.

    You mentioned earlier that you had external processes instead of threads in a different implementation. You could still use that here as another alternative.

    Cheers,
    _

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

    PascalSevran (6th May 2014)

  12. #11
    Join Date
    Apr 2014
    Posts
    6
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Qt/Qml + RTI DDS Application

    Thanks a lot for your answers, I'll try to figure out how to deal with my threads based on what you said.

    As far as splitting the requester and the replier onto 2 external processes, I really dont see how I could launch them from a GUI button click since they need to be running in paralel :s

  13. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,418
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt/Qml + RTI DDS Application

    QProcess

    Cheers,
    _

Similar Threads

  1. Replies: 4
    Last Post: 19th November 2012, 14:35
  2. Replies: 3
    Last Post: 28th October 2011, 23:24
  3. Replies: 3
    Last Post: 5th October 2011, 16:45
  4. Replies: 1
    Last Post: 30th May 2011, 13:46
  5. Replies: 2
    Last Post: 21st November 2010, 18:03

Tags for this Thread

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.