If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
I was wanting to dummy proof a button so the end user couldn't just keep clicking the button while the function was running.
Well, I tried connect/disconnect, enable(true/false) and a combination of the two but the queue just keeps filling up as long as I keep hitting the button so when I am done with the routine then (re)Connect-> the button it just loops over and over until the queue is clean.
This sounds odd since I connect and I disconnect the event queue should ditch (ignore) my button mashing.
Disconnect returns a boolean of whether it was successful; did you check it?
Also, there is a possibility that your OS queues the mouse clicks while your app is unresponsive and "unleashes" them when the app becomes responsive again.
More generally, we'd need to know more about what's going on between the disconnect and the connect (does it block the UI?), what precisely happens when the user clicks multiple times (re-entrency? method called multiple times in a row? etc.)
"Keyboard not detected. Press F1 to continue"
-- Windows
Just glancing at the code it seems it is just a mechanism to set a flag and reset a flag so my code does not go in or out of what it does.
The issue is not that they can reenter my routine (because I can set my own flag to stop that) but there appears to be no mechanism, or at least one I could find, to stop the mashing of the button that stores up the mashing button events *even* when I have disconnected the thing, froze it, disabled it, or baked it at 2500 degrees f.
The behavior is not really surprising, because the events that occur during your longer calculation are only dispatched after you have connected the event handlers already.
So you need a flag to prevent reentrancy and a wxYield() before enabling the button again, so that the pending events are cleared from the queue.
BTW: From a gui point of view i would block the gui like this for at most 1-2 seconds. If the calculation takes any longer, i would display a progress dialog. As that's a modal dialog, it would also prevent multiple button presses, so you wouldn't need this "hack"
Agreed with doublemax, blocking the GUI is the wrong approach (because the OS may queue event, as I explained earlier); I would instead recommend running the long calculation in a thread. Then clicking on the button disables it, starts the thread; when the thread is done, it sends and event to the main thread and the GUI is updated. The fundamental difference is that the OS then doesn't think your app is being unresponsive and won't queue events; events will be processed as usual but wx will see the button is disabled and nothing will happen.
"Keyboard not detected. Press F1 to continue"
-- Windows
doublemax wrote:The behavior is not really surprising, because the events that occur during your longer calculation are only dispatched after you have connected the event handlers already.
So you need a flag to prevent reentrancy and a wxYield() before enabling the button again, so that the pending events are cleared from the queue.
BTW: From a gui point of view i would block the gui like this for at most 1-2 seconds. If the calculation takes any longer, i would display a progress dialog. As that's a modal dialog, it would also prevent multiple button presses, so you wouldn't need this "hack"
You are, of course, correct as it takes about 2.5-3 seconds and the gui goes a gray translucent due to being locked out.
I have my events down but I am getting confused as the best way to handle this.
So, I always write my button click routines that call the real routine (I do this because I reuse the code in other non event driven procedures/routines) and when the button's event fires I wish to show the button as pressed then lock it in the pressed view (easily done) but to disallow any more button presses to be queued until I am ready to react to them again (meaning my real routine is done with whatever it is to do).
So, is there any other way besides a modal of doing this since Yield will (100% sure of this) make the gui go translucent gray which freaks people out (looks like it crashed iow)?
Auria wrote:Agreed with doublemax, blocking the GUI is the wrong approach (because the OS may queue event, as I explained earlier); I would instead recommend running the long calculation in a thread. Then clicking on the button disables it, starts the thread; when the thread is done, it sends and event to the main thread and the GUI is updated. The fundamental difference is that the OS then doesn't think your app is being unresponsive and won't queue events; events will be processed as usual but wx will see the button is disabled and nothing will happen.
What I did was set the bitmap label to the same as SetBitmapSelected then set my flag and off I went. Now you may click the button as many times as you wish and it looks like nothing is happening but in reality it is triggering the event just not acting on it. Then when my routine (will become a wxthread) is done I send the event which resets the bitmaplabel and the flag.