Results 1 to 16 of 16

Thread: Any alternatives to QThread and QProcess for blocking operations in main GUI thread?

  1. #1
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Any alternatives to QThread and QProcess for blocking operations in main GUI thread?

    I am looking for an alternative to QThread and QProcess to perform blocking operations in main GUI thread in such a way that whenever user presses key during processing, corresponding QKeyEvent is discarded. I paste a snippet of code that presents what I want to achieve. But it does not work as I expect, I explain later why.

    Qt Code:
    1. void MyWindow::keyPressEvent(QKeyEvent* keyEvent)
    2. {
    3. if (keyEvent->key() == Qt::Key_F1)
    4. {
    5. PleaseWait waitDlg; // a window covering whole screen and doing nothing
    6. waitDlg.SetDetails("Please wait while processing...");
    7. waitDlg.setWindowModality(Qt::ApplicationModal);
    8. waitDlg.show();
    9. QCoreApplication::processEvents();
    10.  
    11. int status = processData1();
    12. QCoreApplication::processEvents();
    13.  
    14. if (status)
    15. {
    16. if ( message_box::ask("Question") ) // it opens modal dialog and calls exec()
    17. processData2();
    18. else
    19. processData3();
    20.  
    21. QCoreApplication::processEvents();
    22. }
    23.  
    24. processPostActions();
    25. }
    26. }
    To copy to clipboard, switch view to plain text mode 

    Unfortunately when user presses keys during processData1() execution, QKeyEvent objects are not generated, that's why calling QCoreApplication:rocessEvents() does not have any effect except execution of paint events. QKeyPress events are generated, probably in exec() of message_box. This results in QKeyEvent being handled in message_box dialog - it is unexpected behaviour.

    I run my application on Linux on ARM which is pretty slow in a comparison to PC. That's why similar problem occurs whenever I open new dialogs. You can press key which triggers opening of new dialog and before it is actually displayed (it can take up to 1s) press another key, which will be handled in the new dialog - it is again unexpected and not acceptable behaviour.

    Is there a way to affect somehow QT keyboard driver (or however is called the thing which creates QKeyEvents) and erase all queued input keys that come from Linux keyboard driver?

  2. #2
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    you are going about it wrong. of course after you have shown waitDlg, that will have the focus and keypress events should be passed there, not MyWindow anyway!

    Your problem is that your are doing a workflow inside a keypress handler!

    your keyPressEvent should be more like
    Qt Code:
    1. void MyWindow::keyPressEvent(QKeyEvent* keyEvent)
    2. {
    3. if (keyEvent->key() == Qt::Key_F1)
    4. {
    5. emit SomeSignal();
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 
    and you connect the signal to some slot(s) that control workflow for your dialogs.

    In your slot you could set some member variable to guard against multiple entry whilst one workflow is still running. Or use a state machine to get things more tightly controlled.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  3. #3
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    Quote Originally Posted by amleto View Post
    Your problem is that your are doing a workflow inside a keypress handler!
    It is not my problem, it is my intention.

    I know that I can have this things done by usage of signals and QThread or QProcess. But then my code gets more complicated (it would be nice to implement some kind of coroutines for code simplification - are there coroutines in QT?). Everything I need is just to block all input, discard all key events while I'm performing task.

    What do you think about the second half of my question - concerning long lasting opening of dialogs and key events that are not welcomed in new window? To be clear I don't perform any long operations in constructors of dialogs, I just setup UI. Later I call exec() on constructed dialog and that's it, I have to wait up to 1second to see new dialog on the screen... Within this time I can press keys and unfortunately corresponding events will be handled in the new dialog, although IMHO they should be discarded. I guess this problem can not be solved by QThread.

  4. #4
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    Quote Originally Posted by mass85 View Post
    It is not my problem, it is my intention.
    More fool you.

    You have a bad case of 'fix the symptoms, not the problem'.

    I guess you can take a horse to water, but you cannot make it drink. Good day.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  5. #5
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    I agree with amleto.

    You're doing it wrong.

    You're using QCoreApplication:rocessEvents() to keep your UI responsive while doing some lenghty tasks.
    Move that tasks to separate thread and connect thread's finished() signal with dialog hide() or some other signal to remove dialog when thread has finished.
    Also crate dialog using new() and keep a pointer to it in private variable. Then you're key handler looks something like that:
    Qt Code:
    1. if ( !this->dialog_pointer && keyEvent->key() == Qt::Key_F1)
    2. {
    3. //do something
    4. }
    To copy to clipboard, switch view to plain text mode 
    This way even if the event is delivered it will be discarded as long as dialog is there.

    There's several better ways than the one you're taking.

  6. #6
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    Quote Originally Posted by Spitfire View Post
    You're doing it wrong.

    You're using QCoreApplication:rocessEvents() to keep your UI responsive while doing some lenghty tasks.
    This pattern is described in QT documentation, that's why IMHO we should not assume it is wrong.

    Quote Originally Posted by Spitfire View Post
    This way even if the event is delivered it will be discarded as long as dialog is there.
    The problem is that it is not delivered there, neither to waitDlg. It is created much later after actual key press happened and it is delivered to message_box.

    Unfortunately both of you don't seem to notice problem I described. I need a way of discarding keys that were pressed while application was switching dialogs.

  7. #7
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    it's simple. When doing a long process and user inputs should be ignored, put the process in a thread and show a modal progress dialog - that dialog will eat all the events. Unfortunately you don't seem to recognise help when it is given.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  8. #8
    Join Date
    Sep 2011
    Location
    Manchester
    Posts
    538
    Thanks
    3
    Thanked 106 Times in 103 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    That pattern may be desribed in QT docummentation and I'm not saying it's wrong, but its application has to be correct, IMHO it's not in this case.

    You're overcomplicating what you want to do or describing it wrong.

    As to the discarding, if you'd read my example code you'd see that it would do exacly that.
    Simple flag put in correct place can solve your issue, noting more is requried.

  9. #9
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    Then what is the right design pattern for thing as simple as opening of new window? Consider this code:
    Qt Code:
    1. void MainWindow::keyPressEvent(QKeyEvent* keyEvent)
    2. {
    3. if (keyEvent->key() == Qt::Key_F1)
    4. {
    5. HelpDialog help(this);
    6. help.exec();
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 

    If in MainWindow you press quickly F1 three times, the first QKeyEvent will cause to exec HelpDialog, but the other two events will be handled in HelpDialog, which is totally unacceptable, because it may cause some random actions that user is not aware of. Please don't say that it is pointless to press one button three times and that noone will do it, because you can do it just by accident. But there is a better reason for doing such a thing than accident. When process of displaying new window lasts long (let's say 1s) user doubts if the keyboard/application detected if key had been pressed and then he presses it again.

  10. #10
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    statemachine. Like I already said, back in post 2!

    for this simple example you would have three states.

    1) waiting
    2) starting
    3) running

    You can only go from state to state in order: 1->2->3->1 etc.

    Default state is waiting. As soon as f1 is pressed, state is changed to 2). In state 2), keypress does nothing.

    State 2 does the making of new form and exec(). As soon as exec is called, state is changed to running.

    As soon as exec finishes, state changes back to 1.
    Last edited by amleto; 23rd December 2011 at 15:12.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  11. #11
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    If I understand your idea, you want to run exec in QThread. As far as I know QThread is just a worker thread and you cannot use any widgets in it.

  12. #12
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    No, it has nothing at all to do with threads. Where did I mention threads? I mentioned state machine, didn't I?

    and you can 'use' any widget you want in a thread, but you can only make widgets in the main thread.
    Last edited by amleto; 23rd December 2011 at 18:34.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  13. #13
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    Then what is this state machine for? If you do this in main Gui thread you don't need to remember current state, everything happens consecutively like in my last example of code.

  14. #14
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    your code has a problem when user keep pressing buttons. using a statemachine can resolve this problem. Is that the third time I have said it now?
    Last edited by amleto; 23rd December 2011 at 21:09.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  15. #15
    Join Date
    Dec 2010
    Posts
    14
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    You are still not explaining how state machine could solve this problem.

    I think you are missing the fact that generation and delivery of QKeyEvent does not happen in background. There is no concurrency between construction of window and delivery of QKeyEvents. Here is the flow:

    1. QKeyEvent is dispatched to MainWindow.
    --- in the background user presses another two keys ---
    2. keyPressedEvent constructs HelpDialog.
    3. New event loop is started by calling exec() on modal dialog.
    4. In the new loop Linux keyboard driver's output buffer is checked and two new keys are found. (actually I'm not sur how it happens, that's one of the things I'm trying to figure out).
    5. Two QKeyEvent objects are generated for both of new keys.
    6. The first is dispatched to HelpDialog which has focus now.
    7. Later the second one will be dispatched to widget with focus (who knows which).

    This is how it works (more or less) in my system.

  16. #16
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Any alternatives to QThread and QProcess for blocking operations in main GUI thre

    Sorry, for some reason I have been thinking that you had a problem with too many events sent to the main window.

    Anyway, your problem is purely down the event handler (or something else on the main thread) taking up too much time. It is blocking the main thread from handling events quickly, and that is why a key press on mainwindow is getting delayed and sent to another window.

    Move heavy work out of the gui thread - it should not be there anyway.
    Last edited by amleto; 24th December 2011 at 12:17.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar Threads

  1. Replies: 5
    Last Post: 22nd February 2011, 21:21
  2. Replies: 7
    Last Post: 6th November 2010, 08:32
  3. QThread sends signal to main thread immediatly
    By BIllNo123 in forum Newbie
    Replies: 7
    Last Post: 27th August 2010, 10:32
  4. QThread Signal Not Received By Main Thread Slot
    By EF2008 in forum Qt Programming
    Replies: 7
    Last Post: 4th June 2010, 08:06
  5. Determine if QThread::currentThread is main thread?
    By chaoticbob in forum Qt Programming
    Replies: 2
    Last Post: 17th December 2008, 06:26

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.