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.
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:This way even if the event is delivered it will be discarded as long as dialog is there.Qt Code:
if ( !this->dialog_pointer && keyEvent->key() == Qt::Key_F1) { //do something }To copy to clipboard, switch view to plain text mode
There's several better ways than the one you're taking.
This pattern is described in QT documentation, that's why IMHO we should not assume it is wrong.
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.
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.
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.
Then what is the right design pattern for thing as simple as opening of new window? Consider this code:
Qt Code:
{ if (keyEvent->key() == Qt::Key_F1) { HelpDialog help(this); help.exec(); } }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.
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.
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.
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.
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.
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.
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.
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.
Bookmarks