Results 1 to 6 of 6

Thread: Emitting signals between main GUI thread and non-QThread thread

  1. #1
    Join Date
    Feb 2011
    Posts
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Emitting signals between main GUI thread and non-QThread thread

    I'm trying to figure out how to emit Signals from a thread to be captured by Slots in the main GUI thread. The thread is used to read serial port data. The thread is NOT a QThread. It's a generic Win32 thread created via CreateThread().

    The Win32 thread is passed a pointer to a Serial class object. This object has a ThreadProc member function in which the thread runs. The Serial class inherits from QObject and declares the Signal member function.

    The connection between the Signal and Slot is made in the main GUI window constructor. If I leave the connection type out so it picks Automatic, I can emit the Signal from the Serial object as long as it is called from the main GUI thread (as when I'm configuring the Serial object before starting the thread). However, any calls to emit the Signal from within the thread do not arrive at the Slot. If I change the connection type to QueuedConnection, none of the Signals make it to the Slot. Not even the ones called from within the main GUI thread.

    What is this Qt newbie doing wrong? Using Qt 4.7.


    Here are some code snippets:
    Qt Code:
    1. #include <QObject>
    2. class Serial : public QObject
    3. {
    4. Q_OBJECT
    5.  
    6. public:
    7. Serial();
    8. virtual ~Serial();
    9.  
    10. void Run();
    11.  
    12. protected:
    13. static DWORD WINAPI ThreadProc (LPVOID lpArg); // 'lpArg' is a pointer to an instance of this class
    14. DWORD ThreadProc (void); // run-loop of the thread, called by the above static function.
    15.  
    16. signals:
    17. void SerialEventSignal(unsigned int event);
    18. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void Serial::Run()
    2. {
    3. emit SerialEventSignal(1); // works with Automatic connection, fails with QueuedConnection
    4. DWORD dwThreadId = 0;
    5. m_hThread = ::CreateThread(0,0,ThreadProc,LPVOID(this),0,&dwThreadId);
    6. }
    7.  
    8. DWORD WINAPI Serial::ThreadProc(LPVOID lpArg)
    9. {
    10. Serial* pThis = reinterpret_cast<Serial*>(lpArg);
    11. return pThis->ThreadProc();
    12. }
    13.  
    14. DWORD Serial::ThreadProc (void)
    15. {
    16. emit SerialEventSignal(2); // Always fails
    17. while (true)
    18. {
    19. // do stuff
    20. }
    21. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: Emitting signals between main GUI thread and non-QThread thread

    Show us how your slot is declared and used.
    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
    Feb 2011
    Posts
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Emitting signals between main GUI thread and non-QThread thread

    I'm at a new location now and don't have the code in front of me, but it's roughly this.
    Qt Code:
    1. class MainWindow : public [main GUI window inheritance stuff]
    2. {
    3. Serial m_SerialPort;
    4.  
    5. ...
    6.  
    7. private slots:
    8. void SerialEventSlot(unsigned int event);
    9. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. MainWindow::MainWindow()
    2. {
    3. ...
    4.  
    5. connect(&m_SerialPort, SIGNAL(SerialEventSignal(unsigned int)), this, SLOT(SerialEventSlot(unsigned int))); // this call seems to fail if I try to use 'Qt::QueuedConnection'
    6. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void MainWindow::on_buttonClicked()
    2. {
    3. m_SerialPort.Run(); // This causes the receiver thread to be created.
    4. }
    5.  
    6. void MainWindow::SerialEventSlot(unsigned int event)
    7. {
    8. std::cout << "Detected a Serial Event: " << event << std::endl;
    9. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: Emitting signals between main GUI thread and non-QThread thread

    Please dump the QThread::currentThreadId() value (it's a static method) before creating the worker thread and then before emitting the signal. Are they the same or different?
    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
    Feb 2011
    Posts
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Emitting signals between main GUI thread and non-QThread thread

    I will post the results of doing the dump tomorrow when I have access to my system again.

    EDIT: In the mean time, where should I look for information on how threading works in Qt? The official documentation is rather lacking. I still don't understand how run() and exec() are supposed to be used. I've even read some blogs about how most people are apparently "doing it wrong" when it comes to threading because that's what the documentation says to do (overriding run()).

    What I'm looking for is a thread that can block forever on a call to WaitForSingleObject() (Win32 API) and still emit Signals when not blocked. I don't care if the thread used is a QThread, a native Win32 thread, or something else. But everything I understand from the doucmentation and doing searches is you can't block on something like WaitForSingleObject() and still emit Signals (because exec() isn't being executed?). Is this true? If so, what's the work-around for blocked threads and Signals/Slots usage?

    Thanks.
    Last edited by jansenmd; 22nd February 2011 at 03:07. Reason: updated contents

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

    Default Re: Emitting signals between main GUI thread and non-QThread thread

    If a thread is blocked, it's not scheduled by the operating system, so it can't do anything, be it emitting a signal or adding two ints together. Your design is just plainly wrong for the current computer architectures. Maybe try describing what is the ultimate effect you want to achieve and we'll help you find a good design for it.
    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. Replies: 7
    Last Post: 6th November 2010, 08:32
  2. QThread sends signal to main thread immediatly
    By BIllNo123 in forum Newbie
    Replies: 7
    Last Post: 27th August 2010, 10:32
  3. QThread Signal Not Received By Main Thread Slot
    By EF2008 in forum Qt Programming
    Replies: 7
    Last Post: 4th June 2010, 08:06
  4. Replies: 16
    Last Post: 7th October 2009, 08:17
  5. Determine if QThread::currentThread is main thread?
    By chaoticbob in forum Qt Programming
    Replies: 2
    Last Post: 17th December 2008, 06:26

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.