Results 1 to 10 of 10

Thread: wait until a signal is processed

  1. #1
    Join Date
    Feb 2011
    Posts
    354
    Thanks
    17
    Thanked 27 Times in 24 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows

    Default wait until a signal is processed

    Hi all, I am developing a multi-threaded app that emits signals processed in another threads. I need to wait for a signal to be processed. According to the documentation, Qt::BlockingQueuedConnection seems to be right for that case, but the following code doesn't work (connect returns false):

    Qt Code:
    1. bool con = connect(thread, SIGNAL(mysignal2(MyClass &)), this, SLOT(myslot2(MyClass &)), Qt::BlockingQueuedConnection);
    To copy to clipboard, switch view to plain text mode 

    The same problem is also with Qt::QueuedConnection, but if a don't specify the connection type, it works fine, but of course doesn't wait for a signal processing.

    So, this code works:
    Qt Code:
    1. bool con = connect(thread, SIGNAL(mysignal2(MyClass &)), this, SLOT(myslot2(MyClass &)));
    To copy to clipboard, switch view to plain text mode 

    I use Q_DECLARE_METATYPE and call qRegisterMetaType before establishing a connection. Please, give me a tip what can be wrong here.

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

    Default Re: wait until a signal is processed

    Do you get a runtime warning about the connections? How do you use qRegisterMetaType? In general what you have will probably not work because you are using non-const references. Either use const references or if you have to modify the objects being passed through the signal, use pointers. And think twice if you really need a signal to handle this situation. Do you expect more than one receiver to connect to it? Do you expect a situation that no slot is connected to the signal? If answer to any of the two last questions is "no" then you probably shouldn't be using signals at all.
    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
    354
    Thanks
    17
    Thanked 27 Times in 24 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows

    Default Re: wait until a signal is processed

    i have MyClass declared as
    Qt Code:
    1. class MyClass
    2. {
    3. };
    4.  
    5. Q_DECLARE_METATYPE(MyClass)
    To copy to clipboard, switch view to plain text mode 

    and this is how i establish my connections:
    Qt Code:
    1. MyClass myclass;
    2.  
    3. qRegisterMetaType<MyClass>();
    4.  
    5. bool con;
    6. con = connect(thread, SIGNAL(mysignal1(int)), this, SLOT(myslot1(int)), Qt::BlockingQueuedConnection);
    7. con = connect(thread, SIGNAL(mysignal2(MyClass &)), this, SLOT(myslot2(MyClass &)), Qt::BlockingQueuedConnection);
    To copy to clipboard, switch view to plain text mode 

    i see the following in the output window:
    Qt Code:
    1. QObject::connect: Cannot queue arguments of type 'MyClass&'
    2. (Make sure 'MyClass&' is registered using qRegisterMetaType().)
    3. The program '[13916] testsignals.exe: Native' has exited with code 0 (0x0).
    To copy to clipboard, switch view to plain text mode 

    maybe the issue is caused by reference?

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

    Default Re: wait until a signal is processed

    You can try registering the reference as well but in my opinion this doesn't make much sense as the data will get copied anyway.
    Qt Code:
    1. qRegisterMetaType<MyClass&>("MyClass&");
    To copy to clipboard, switch view to plain text mode 

    By the way, are you sure about the affinity of your "thread" object? Can you show us how you declare and use 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.


  5. #5
    Join Date
    Feb 2011
    Posts
    354
    Thanks
    17
    Thanked 27 Times in 24 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows

    Default Re: wait until a signal is processed

    just tried
    Qt Code:
    1. qRegisterMetaType<MyClass&>("MyClassRef");
    To copy to clipboard, switch view to plain text mode 
    it can't be compiled.

    and i found the following code works:
    Qt Code:
    1. bool con = connect(thread, SIGNAL(mysignal3(MyClass)), this, SLOT(myslot3(MyClass)), Qt::BlockingQueuedConnection);
    To copy to clipboard, switch view to plain text mode 

    here is the code where the thread is created and started:
    Qt Code:
    1. testsignals::testsignals(QWidget *parent, Qt::WFlags flags)
    2. : QMainWindow(parent, flags)
    3. {
    4. ui.setupUi(this);
    5.  
    6. MyThread *thread = new MyThread(this);
    7.  
    8. qRegisterMetaType<MyClass>();
    9.  
    10. bool con;
    11. con = connect(thread, SIGNAL(mysignal1(int)), this, SLOT(myslot1(int)), Qt::BlockingQueuedConnection);
    12. con = connect(thread, SIGNAL(mysignal2(MyClass &)), this, SLOT(myslot2(MyClass &)), Qt::BlockingQueuedConnection);
    13.  
    14.  
    15. thread->start();
    16. thread->wait();
    17. }
    To copy to clipboard, switch view to plain text mode 


    and here is the thread's run procedure:
    Qt Code:
    1. void MyThread::run()
    2. {
    3. emit mysignal1(44);
    4.  
    5. MyClass m;
    6. emit mysignal2(m);
    7. }
    To copy to clipboard, switch view to plain text mode 

    i know passing stack allocated data by reference isn't good, but just for test...
    Last edited by mentalmushroom; 2nd March 2011 at 12:35.

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

    Default Re: wait until a signal is processed

    It's not about stack or non-stack. It's about mutable and non-mutable. A reference to an object is mutable, a copy of the object is not. Thus the latter works and the former doesn't.

    And your thread affinity is ok - the Thread object works in context of the main thread and the "m" object works in context of the worker thread.
    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
    Feb 2011
    Posts
    354
    Thanks
    17
    Thanked 27 Times in 24 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows

    Default Re: wait until a signal is processed

    ok, but is there any way to pass a reference or const reference to signal/slot? actually i need to pass a QExplicitlySharedPointer as a signal/slot argument, and it seems if i don't pass it as a reference, i have to implement a copy constructor and possibly assignment operator that is inconvenient when such signal/slots are used in a several different classes with a lot of member values.

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

    Default Re: wait until a signal is processed

    A const reference is not a problem, it should work out of the box. Passing a reference doesn't make sense. As I said, before reaching the slot, the data will be copied so you'd operate on a copy anyway. Better use pointers. But before you do that, as I already said, think a couple of times if signals are a good approach here. It might be much easier to do what you want using events, for instance like this:
    Qt Code:
    1. MyEvent event;
    2. event.setSomeData(data);
    3. QApplication::sendEvent(someObjectInAnotherThread, &event); // this will block
    4. data = event.data(); // modified content
    To copy to clipboard, switch view to plain text mode 

    or using a classical approach with a wait condition blocking the sending thread.
    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.


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

    mentalmushroom (3rd March 2011)

  10. #9
    Join Date
    Feb 2011
    Posts
    354
    Thanks
    17
    Thanked 27 Times in 24 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows

    Default Re: wait until a signal is processed

    strange, i've just noticed when calling QCoreApplication::sendEvent on some object in another thread the following error appears: "ASSERT failure in QCoreApplication::sendEvent: Cannot send events to objects owned by a different thread. …"assertion_failure.png

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

    Default Re: wait until a signal is processed

    Yes, unfortunately that's true. But you can have the same effect using a wait condition. Post the event, wait on the condition until it is signalled by the handling object when the data is ready.
    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. how to resume QThread::wait()?
    By naturalpsychic in forum Qt Programming
    Replies: 6
    Last Post: 26th January 2011, 23:07
  2. Events not processed using QMfcApp::pluginInstance
    By nokkie in forum Qt Programming
    Replies: 1
    Last Post: 29th April 2010, 00:23
  3. Replies: 3
    Last Post: 19th January 2010, 20:26
  4. How to wait 2 seconds before continue
    By raphaelf in forum Newbie
    Replies: 3
    Last Post: 25th June 2008, 14:36
  5. Wait for a signal
    By adonel in forum Qt Programming
    Replies: 1
    Last Post: 13th May 2008, 19:53

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.