Results 1 to 10 of 10

Thread: Slot in main thread (gui), signal from background thread - how?

  1. #1
    Join Date
    Nov 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Slot in main thread (gui), signal from background thread - how?

    Hello,

    I have simple gui application. This application creates new background thread. There are some operations to execute in the thread with progress reporting to gui thread.

    Some code:
    backthread.h:
    Qt Code:
    1. #ifndef BACKTHREAD_H
    2. #define BACKTHREAD_H
    3.  
    4. #include <QThread>
    5. #include "Counter.h"
    6.  
    7.  
    8. class BackThread : public QThread
    9. {
    10. public:
    11. virtual void run();
    12.  
    13. private:
    14. Counter counter;
    15.  
    16.  
    17. };
    18.  
    19. #endif // BACKTHREAD_H
    To copy to clipboard, switch view to plain text mode 

    backthread.cpp:
    Qt Code:
    1. #include "backthread.h"
    2.  
    3. void BackThread::run()
    4. {
    5. int i=0;
    6. while(1)
    7. {
    8. counter.setValue(i);
    9. sleep( 1 );
    10. qDebug( "Ping!" );
    11. i+=10;
    12. if(i==100) i=0;
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 

    Counter.h:
    Qt Code:
    1. #ifndef COUNTER_H
    2. #define COUNTER_H
    3.  
    4.  
    5. #include <QObject>
    6.  
    7. class Counter : public QObject
    8. {
    9. Q_OBJECT
    10.  
    11. public:
    12. Counter() { m_value = 0; }
    13.  
    14. int value() const { return m_value; }
    15.  
    16. public slots:
    17. void setValue(int value);
    18.  
    19. signals:
    20. void valueChanged(int newValue);
    21.  
    22. private:
    23. int m_value;
    24. };
    25.  
    26. #endif
    To copy to clipboard, switch view to plain text mode 

    Counter.cpp:
    Qt Code:
    1. #include "Counter.h"
    2.  
    3. void Counter::setValue(int value)
    4. {
    5. if (value != m_value) {
    6. m_value = value;
    7. emit valueChanged(value);
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    And in main windows class:
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3.  
    4. MainWindow::MainWindow(QWidget *parent)
    5. : QMainWindow(parent), ui(new Ui::MainWindow)
    6. {
    7. ui->setupUi(this);
    8.  
    9. BackThread th;
    10. th.start();
    11. }
    12.  
    13. MainWindow::~MainWindow()
    14. {
    15. delete ui;
    16. }
    To copy to clipboard, switch view to plain text mode 

    There is Progress Bar widget in main window, and its value should be updated when Counter::m_progress changes. But I have no idea how to define slot for main window class to receive notifications from thread.

    Can you help me?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Slot in main thread (gui), signal from background thread - how?

    Your construction is incorrect. Objects that are members of QThread subclass live in the thread where the QThread object was created, not in the one the QThread object controls. You are likely to run into trouble later. To avoid the trouble you can move the QThread object to the thread it contols using QObject::moveToThread().

    Now for your question - there is nothing special you have to do, just create a slot in your window that will take an integer and then issue a connect statement between counter's and your window's signals/slots. Just remember you need pointers to both objects available in the same moment. It might be easier if you declare a signal in your QThread subclass and connect counter's signal to the thread controller's signal and then connect the thread's signal to a slot in main window.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Nov 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Slot in main thread (gui), signal from background thread - how?

    To avoid the trouble you can move the QThread object to the thread it contols using QObject::moveToThread().
    Hmm ok, but where or when I should call this method? In Counter constructor, call from gui thread, etc...?

    It might be easier if you declare a signal in your QThread subclass and connect counter's signal to the thread controller's signal and then connect the thread's signal to a slot in main window.
    Do you mean I sholud define slot in BackThread and connect signal from Counter to it, and then emit signal from slot in BackThread to catch it in gui thread?

    I'm not really sure why I need Counter class? What if I try to emit signal from BackThread::run instead of using Counter class?

    Sorry for stupid questions, I'm totally new in QT...

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Slot in main thread (gui), signal from background thread - how?

    Quote Originally Posted by giaur View Post
    Hmm ok, but where or when I should call this method? In Counter constructor, call from gui thread, etc...?
    Hmm... actually it just came to my mind it's not enough. You need to move the Counter object as well. You can do it at any time after you call QThread::start() but you have to do it from within the main thread (you can only push an object to a different thread, not pull it in from another thread).

    Do you mean I sholud define slot in BackThread and connect signal from Counter to it, and then emit signal from slot in BackThread to catch it in gui thread?
    No, you can connect one signal to another signal. This way when one is fired, the other one is emitted as well (we call it signal propagation).

    I'm not really sure why I need Counter class? What if I try to emit signal from BackThread::run instead of using Counter class?
    You don't need it. Unless you want it to do something else besides holding that integer.

    Sorry for stupid questions, I'm totally new in QT...
    That's fine. Just remember it is Qt not QT. The latter is technology of a known fruit company.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Nov 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Slot in main thread (gui), signal from background thread - how?

    You need to move the Counter object as well. You can do it at any time after you call QThread::start() but you have to do it from within the main thread
    Should I create method in BackThread, that will perform this, and call it from main thread after QThrea::Start is called?

    No, you can connect one signal to another signal. This way when one is fired, the other one is emitted as well (we call it signal propagation).
    Hmm, I'm little confused now. Could you add this to code I posted, with some explanation?

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Slot in main thread (gui), signal from background thread - how?

    Quote Originally Posted by giaur View Post
    Should I create method in BackThread, that will perform this, and call it from main thread after QThrea::Start is called?
    Just call it right after you call start() on the thread.


    Hmm, I'm little confused now. Could you add this to code I posted, with some explanation?
    Qt Code:
    1. class Counter : public QObject {
    2. Q_OBJECT
    3. public:
    4. Counter() { m_counter = 0; }
    5. void setValue(int v) {
    6. if(m_counter == v) return;
    7. m_counter = v;
    8. emit valueChanged(v);
    9. }
    10. signals:
    11. int valueChanged(int);
    12. };
    13.  
    14. class Thread : public QThread {
    15. Q_OBJECT
    16. public:
    17. Thread() : QThread() {
    18. connect(&counter, SIGNAL(valueChanged(int)), this, SIGNAL(counterValueChanged(int)));
    19. }
    20. void run() { ... }
    21. void moveObjectsToThread() {
    22. moveToThread(this);
    23. counter.moveToThread(this);
    24. } // required to get around private scope
    25. signals:
    26. void counterValueChanged(int);
    27. private:
    28. Counter counter;
    29. };
    30.  
    31. // ...
    32. Thread thread;
    33. connect(&thread, SIGNAL(counterValueChanged(int)), ...);
    34. thread.start();
    35. thread.moveObjectsToThread();
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 27th November 2009 at 23:18.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Nov 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Slot in main thread (gui), signal from background thread - how?

    This doesn't work:

    Qt Code:
    1. Thread thread;
    2. connect(&thread, SIGNAL(counterValueChanged(int)), ...);
    3. thread.start();
    4. thread.moveObjectsToThread();
    To copy to clipboard, switch view to plain text mode 

    No signals emiited at all and iwarning in console is:
    QThread: Destroyed while thread is still running
    But this works fine:
    Qt Code:
    1. Thread *thread;
    2. connect(thread, SIGNAL(counterValueChanged(int)), ...);
    3. thread->start();
    4. thread->moveObjectsToThread();
    To copy to clipboard, switch view to plain text mode 

    Thread is created and started in main window constructor. In the first case - QThread object is destroyed without stopping thread. So, the thread works, but without any control ("Ping" commands are printed as weel). Why?

  8. #8
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Slot in main thread (gui), signal from background thread - how?

    The first thread will be destroyed when the variable goes out of scope, whilst the second will not.

  9. #9
    Join Date
    Nov 2009
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Slot in main thread (gui), signal from background thread - how?

    Ok, understood... another question - should I delete thread object? Or it is disposed already after thread finishes?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,013 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Slot in main thread (gui), signal from background thread - how?

    The QThread object has nothing to do with the lifetime of the thread it controls. It's an object like any other. If it was autodeleted, all applications allocating QThread objects on stack would not work.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. pthread instead QThread
    By brevleq in forum Qt Programming
    Replies: 8
    Last Post: 23rd December 2008, 08:16
  2. Connection of custon signals/slots
    By brevleq in forum Qt Programming
    Replies: 2
    Last Post: 23rd December 2008, 08:04
  3. signal and slot across threads having event loop
    By travis in forum Qt Programming
    Replies: 6
    Last Post: 6th November 2007, 00:56
  4. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 07:13
  5. Replies: 10
    Last Post: 20th March 2007, 23:19

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.