Results 1 to 9 of 9

Thread: [SOLVED?] Emiting signals from a QThread is blocking my QDialog.

  1. #1
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default [SOLVED?] Emiting signals from a QThread is blocking my QDialog.

    Hello,

    Here is what i have so far:
    - A QDialog, with various controls in it (Buttons, Sliders, Combo Boxes etc).
    - The QDialog also contains a custom progress bar i made, which has one slot named "setPercentage(int)".
    - The Dialog starts a thread, which emits a signal named "percentageChanged(int)".
    - In my QDialog, i connect the QThread's signal directly to my progress bar's slot.

    The observed issue is, when the thread is running and the progress bar updating, the controls in my QDialog are frozen, just like if there were no thread.

    If i just dont connect the thread to the pbar, it's ok, all are very fluid.

    Anyone has a clue on how to avoid this?

    Thanks ^^

    [EDIT:] The only solution i see is, give a pointer to the PBar to the QThread, so it directly manages to set the percentage... but i feel like it's very ugly.
    [EDIT2:] I think i know why this behaviour happens: in my PBar's setPercentage slot, i do a repaint(). Which is done too fast probably. Instead, i would like to "queue" a repaint event, so if the event loop finds two at the same time, it only repaint once...
    Last edited by hickscorp; 17th April 2007 at 14:37.

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    Could you show us some code? Especially how do you create the thread and how you emit the signal...

    The only solution i see is, give a pointer to the PBar to the QThread, so it directly manages to set the percentage... but i feel like it's very ugly.
    It is quite "illegal". Interface objects must be modified only by the interface thread.

  3. #3
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    Oh, I see the problem now.
    Don't connect the thread signal to the progress slot. Instead connect it to a slot in the dialog, in which you call setValue( int ).

    Connecting it to setValue, as you do now, causes a DirectConnection to be made. This is why your GUI blocks - the worker thread updates your progress all the time.

    Do as I said an it will work.

    regards

  4. The following user says thank you to marcel for this useful post:

    hickscorp (17th April 2007)

  5. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    I think i know why this behaviour happens: in my PBar's setPercentage slot, i do a repaint(). Which is done too fast probably. Instead, i would like to "queue" a repaint event, so if the event loop finds two at the same time, it only repaint once...
    No, not true...

  6. #5
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    Hmm it is very complicated to show you some code, especially for the QDialog.
    But here are some stuff which can help:

    How i connect the thread to the PBar (From my QDialog):
    Qt Code:
    1. connect( thrdProcessing, SIGNAL(percentDone(int)), prgBrCoreStatus, SLOT(setPercentage(int)) );
    2. connect( thrdProcessing, SIGNAL(stepDone(int, int)), prgBrCoreStatus, SLOT(setStep(int, int)) );
    To copy to clipboard, switch view to plain text mode 

    How i start the thread (From my QDialog):
    Qt Code:
    1. if (!thrdProcessing->isRunning()) {
    2. // Start the core...
    3. thrdProcessing->start();
    4. } else
    5. setWindowTitle(tr("The core is already running."));
    To copy to clipboard, switch view to plain text mode 

    Also, attached is the full source code of my PBar.

    Thanks a lot again Marcel
    Pierre

    [EDIT:] FYI: The two attached files have been made with Visual Studio... under Windows. i recommend you to set the tabs space to 4 if you're using Kdevelop, i had this issue earlier
    Attached Files Attached Files

  7. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    OK.

    Instead of repaint, use update().
    repaint() causes an immediate pintEvent(). update() will post it in the event queue, and it will be executed in the next event loop.

    Try this first.

    EDIT: I'm in Windows( VS 2003 )

    regards

  8. The following user says thank you to marcel for this useful post:

    hickscorp (17th April 2007)

  9. #7
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    Marcel,

    I just have tested with the "update" instead of the "repaint": no more freeze, but much "lag".
    But i didnt see your previous post so i just changed this too, the lag doesnt go away.

    In fact, the thread was connected to the dialog and i had this lag, so i thought maybe i should connect it to the PBar =/

    Any other clue? Maybe i should put a timer in the progress bar, which checks let's say each 50ms to update()?

    Pierre.

  10. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    How many times do you emit the signal?
    You should test before emitting the setProgress signal, to make sure you don't emit the same value more than one time. This happened to me some time ago. You should emit a single signal for every value that you set.

    Emitting a lot of signals (which are turned into events ) can block the interface.

    EDIT: Every time you emit the signal from the thread you should look at the previous value you emitted ( initially 0 ), and if they are not equal then it's ok to emit. Otherwise you wait for the next value.

    Regards.
    Last edited by marcel; 17th April 2007 at 14:32.

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

    hickscorp (17th April 2007)

  12. #9
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Emiting signals from a QThread is blocking my QDialog.

    Your solution is a good solution, but in certain cases can't apply to me
    But i suspect i'll see the problem when i'll put the real, heavy, slow processement in my thread (For now i have a fake processement routine in the thread, to test).

    I have put a test on the last percentage emited, if it's the same it doesnt emit again. Still minimal lag, but now the GUI is usable

    Thanks a lot, i'll come back post here if the problem is back after i put the real code in the thread.

    Pierre.

Similar Threads

  1. emiting signals from const member functions !?
    By sunil.thaha in forum Qt Programming
    Replies: 2
    Last Post: 25th March 2006, 11:29
  2. Replies: 2
    Last Post: 6th January 2006, 21:15

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.