Results 1 to 9 of 9

Thread: Help with QThread

  1. #1
    Join Date
    Jul 2006
    Posts
    10
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Help with QThread

    Hi, i am new in thread programming with c++. Ive used threads in Java.

    My problem is this:

    I have a class with several methods. All this methods MUST be runned as thread because attemps to connect to external devices and i dont want to block my app. If i subclass QThread then i must have a run method reimplemented. Now the ugliest solution would be a huge case or something like that to call the method i want. But have to be another way. In hava there are anonymous classes so is easier. How can i solve this??


    Thanks very much.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Quote Originally Posted by manucorrales View Post
    If i subclass QThread then i must have a run method reimplemented. Now the ugliest solution would be a huge case or something like that to call the method i want.
    I'm not sure what's the problem since there is no difference between C++ and Java in that matter (except for the built-in monitor, which is present in Java).

    You can always avoid switch statements using a command pattern (i.e. with a set of objects resembling jobs/commands and a queue with proper synchronization).

  3. #3
    Join Date
    Jul 2006
    Posts
    10
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Thanks. Can you be a little more specific on the Command Pattern? I have this:

    Class A
    {
    void method1(){};
    void method2(){};
    void method3(){};
    }


    and when i call a method of an object of this class, must run in background. The only solution i find so far is to make an inner sublclass of QThread inside each method and in the reimplemented run method put my code. Then create myThread and call start.

  4. #4
    Join Date
    Jul 2006
    Posts
    10
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Maybe i am doing this wrong. My initial problem is this: i have to call a methos wich tries to connect to an fiscal printer. I would like to show a dialog that says: "Trying to cennect, please wait" blocking the user but with the possibility of cancel. While showing this dialog, the method i running and trying to connect. Then, when the connection fails or success do something else.

    Thanks for your help!

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Quote Originally Posted by manucorrales View Post
    I would like to show a dialog that says: "Trying to cennect, please wait" blocking the user but with the possibility of cancel. While showing this dialog, the method i running and trying to connect. Then, when the connection fails or success do something else.
    Then you have two options:
    1. use non-blocking I/O and QApplication::processEvents(),
    2. create another thread that will communicate with the printer.


    If you use the second approach, all you need is signals & slots mechanism and queued connections. When you invoke a slot through queued connection, Qt will send an event to the thread and it will pick it up and invoke proper slot. Then you can emit a signal that operation was completed.

    Another way is to subclass QEvent and create classes that represent "commands" like ConnectEvent or similar and send it to the thread (this way you reuse the Qt event loop and you don't have to bother with synchronization). Those new events can share a common interface, so your thread might look like this:
    Qt Code:
    1. void PrinterThread::run()
    2. {
    3. exec();
    4. }
    5.  
    6. void PrinterThread::customEvent( QEvent *event )
    7. {
    8. CommandEvent *cmd = dynamic_cast< CommandEvent *>( event );
    9. if( cmd != 0 ) {
    10. cmd->perform( state ); // state holds all necessary information, like file descriptors
    11. }
    12. else {
    13. // error
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 
    This way you don't need any switch statements.

    But IMO the approach with signals & slots is much easier to implement (and de facto it's the same thing --- only Qt implements part of it for you). Just don't forget about invoking exec() and that the connections must be queued.

    As for the non-blocking I/O: all depends on the way you communicate with the printer. If it expects you to answer within given time or it has a short output buffer, it might not be applicable. Also wrap it in some kind of singleton class, because such code can get a bit messy. The obvious benefit is that you don't use another thread just to communicate with the printer.

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

    manucorrales (8th October 2006)

  7. #6
    Join Date
    Jul 2006
    Posts
    10
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Where can i found info on the non blocking I/O and processEvents() ??

    I cant find on the assistant.

  8. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Quote Originally Posted by manucorrales View Post
    Where can i found info on the non blocking I/O and processEvents() ??
    Here:
    http://doc.trolltech.com/4.1/qcoreap...#processEvents
    http://doc.trolltech.com/4.1/qsocketnotifier.html

    and also `man 2 select`.

  9. The following user says thank you to jacek for this useful post:

    manucorrales (8th October 2006)

  10. #8
    Join Date
    Jul 2006
    Posts
    10
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Sorry i keep asking you. Can you explain to me a little more the queue and slot and signals approach?

    Thanks!!

  11. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Help with QThread

    Quote Originally Posted by manucorrales View Post
    Can you explain to me a little more the queue and slot and signals approach?
    Sure. It's quite easy:
    Qt Code:
    1. class PrinterThread : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. ...
    6. public slots:
    7. void foo( const QString& str );
    8.  
    9. signals:
    10. void bar();
    11. ...
    12. };
    13.  
    14. void PrinterThread::run()
    15. {
    16. exec(); // <- this is very important
    17. }
    18.  
    19. void PrinterThread::foo( const QString& str )
    20. {
    21. ...
    22. emit bar();
    23. ...
    24. }
    25.  
    26. ...
    27. connect( someObject, SIGNAL( someSignal( const QString& ) ), printerThread, SLOT( foo( const QString& ) ), Qt::QueuedConnection );
    28. connect( printerThread, SIGNAL( bar() ), someObject, SLOT( barReceiver() ), Qt::QueuedConnection );
    29. ...
    To copy to clipboard, switch view to plain text mode 
    As you can see you don't need much to get it work.

    When you invoke foo() slot through a queued connection (i.e. using a signal --- don't even try to invoke it directly), Qt will create a QEvent object, copy all parameters and post that event to the PrinterThread event loop. Later PrinterThread will pick that event, invoke the foo() slot and return back to the event loop to wait for another event --- and that's all.

    If you want to subclass QThread (as in the above example), make sure that you use queued connections (direct and automatic connections won't work).

    Also you can try to do it like this:
    Qt Code:
    1. // implements the communication protocol
    2. // only PrinterThread should use it
    3. class PrinterController : public QObject
    4. {
    5. Q_OBJECT
    6. public:
    7. ...
    8.  
    9. public slots:
    10. void doSomething();
    11.  
    12. signals:
    13. void done();
    14. ...
    15. };
    16.  
    17. // provides printer interface to the rest of the application
    18. class PrinterThread : public QThread
    19. {
    20. Q_OBJECT
    21. public:
    22. ...
    23. signals:
    24. void done();
    25. void doSomething();
    26. }
    27.  
    28. void PrinterThread::run()
    29. {
    30. PrinterController controller;
    31. connect( this, SIGNAL( doSometing() ), &controller, SLOT( doSomething() ) );
    32. connect( &controller, SIGNAL( done() ), this, SIGNAL( done() ) );
    33. exec();
    34. }
    35.  
    36. ...
    37. connect( printerThread, SIGNAL( done() ), someObject, SLOT( continueWork() ) );
    38. printerThread->doSomething(); // this behaves just as a non-blocking call
    39. ...
    To copy to clipboard, switch view to plain text mode 
    With this approach you don't have to remember about adding Qt::QueuedConnection and you get a non-blocking interface to your printer.

    Just remember that Qt will copy all parameters, even if you use const references. If it complains that you can't send SomeCustomType through queued connection, then it means that you have to register that type first with qRegisterMetaType() (search the forum for more info about this).

  12. The following user says thank you to jacek for this useful post:

    manucorrales (18th October 2006)

Similar Threads

  1. QTimer and QThread
    By TheKedge in forum Qt Programming
    Replies: 4
    Last Post: 21st September 2006, 14:52
  2. how to use QHttp inside QThread in Qt3
    By alusuel in forum Qt Programming
    Replies: 3
    Last Post: 14th July 2006, 11:19
  3. Posting custom events to a subclass of QThread
    By jpn in forum Qt Programming
    Replies: 3
    Last Post: 4th July 2006, 15:49
  4. Replies: 4
    Last Post: 10th May 2006, 22:37
  5. Is it possible to create a QThread without inheriting ?
    By probine in forum Qt Programming
    Replies: 6
    Last Post: 23rd March 2006, 22:51

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.