I have worked with Keyboard Listeners before, but for this current program that I'm working on I am trying to do the exact opposite. I want to have a timer running in the background, and every thirty seconds the pc that it is running on thinks that a key has been pressed. I know that there is a way to do it, but I don't know what to research because I don't know what it is called. Can anyone give me some recommendations? or links?
So here's my problem. I've looked at pyautogui, and pywinauto so far. In terms of what I would like to do, I would like to simulate mouse and keyboard inputs to a non-active window that the user is currently not using, and not actually interrupt what the user is doing. In pyautogui, it forces actual mouse movement which makes it impossible for me to do other tasks while such a script is running.
I have a large data acquisition and control program written in Python3.4.2 using GUI mostly developed on Glade 3.18.3, Gtk3.0 GObject running Debian 8 with XFCE.
There are timers that keep doing things, and these work fine. After startup, the program runs for some 3 - 7 days, then suddenly, all of the windows go blank and stay blank. Other applications are not affected. Memory and CPU usage is modest.
There are no indications of problems prior to the windows going blank. The windows show their title bars and respond normally to minimize, restore, move to another Workspace, etc. It looks like they are not getting repainted - no widgets are visible at all. The code is way too large to post here, and I am not able to isolate a specific problem area for lack of obvious symptoms other than the blank screens. There are no error messages or warnings.
The timers continue to run, acquire data and control things. This happens whether the program is run from the command line or under PyDev in Eclipse.
Things I have tried:
In the main timer loop, I put code to look for a file, and then exec the command in it, printing the results, so I have been able to mess with the program in real time:
Replace the usual Gtk.main() with a while loop whose variable, if not made false, will re-execute the Gtk.main(). Executing Gtk.main.quit() stops Gtk.main and starts it again. Windows still blank. Did this repeatedly to no avail.
Experimented with garbage collection with GC. Collecting garbage makes no different. Windows still blank.
Put in code to print percent of time consumed by the timer loops. Fairly steady around 18 - 20% of available CPU time, so nothing is hogging the CPU preventing re-paint.
I have a button that clears a label. I read the label, then executed a builder.get_object(...).activate command to the button. I re-read the label and it was now properly blank. So events and widgets appear to be working normally, at least to some extent.
Finally, if I click on the close X on the title bar, XFCE asks me if I want to wait or close now. So it seems as though there may be a disconnection or problem with signals and the OS, even though XXX.activate() works.
Web searching is in vain. Does anybody have ideas of what might be happening, useful diagnostics, or other suggestions? Many thanks!
April 27, 2017 Update:
I have taken two substantial steps to mostly work around problems. First, partly in response to a couple of Gtk crashes over the last few months, instead of ending the main program with:
Gtk.main()
I end with:
while wannalive:
try:
Gtk.main()
except:
pass
wannalive is True until user does a quit, so recovery is instant.
Second, I grouped all of the code for each window setup and initial population of static items into two functions. I also made another function for closing a window. These functions propagate to children, grandchildren windows. A function in the top window first, closes, then re-creates all windows, with one call. In operation, there are overlaps in what windows exist, but that is not a problem.
Above, I describe that I can inject code with an external program. The external program has a button that injects a call to that third function. In about five seconds or less, the result of a single button click is to replace all blank windows with functional windows. For my purposes in a controlled environment with a trained operator, this is acceptable.
Next, let me address the relationship between the timer loops and GUI events processing. I do use GObject.timeout_add(ms, somefunction). Experiment shows that a button that calls time.sleep(5) stalls the timer. Experiment shows that injecting time.sleep(5) in the timer loop stalls the GUI. This is consistent with my belief (correct me if I am wrong) that Python runs on a single thread. Therefore, bad code caught in an infinite loop should stall both the GUI and the timer loop. (The program has one timeout_add call.)
I would like to add a keystroke handler to my Linux system (actually Ubuntu Linux, but pointers to X11 generally will be helpful).
The goal is simple enough in principle, I have a "drawing" program that lets me write on a transparent panel. I want to have a single keystroke that toggles this from the top to the bottom (and back again) of the window stack.
I guess I need to interact with the window manager, but that's where my ideas run out. Any suggestions for research directions?
Thanks,
Toby
I am trying to write a program that monitors when the screen has been redrawn.
Meaning if any part of any window is redrawn, then the program is notified.
As far as I understand I should use a journal record hook like at
http://www.vbaccelerator.com/home/vb/code/libraries/Hooks/Journal_Record_Hooks/article.asp
However, I do not understand which MSG type would get me the WM_PAINT events (WH_CALLWNDPROC and WH_CALLWNDPROCRET do not seem to do the job). I'm not even sure that WM_PAINT is what I'm looking for...
Basically, if I knew when the DC associated with GetDesktopWindow() has changed then my problem would be solved.
Question is: How do you monitor screen updates?
I don't believe this is possible without hooking the display driver. I can imagine there would be some serious performance implications if it were possible in general...
You would be better taking a screenshot every second or whatever. Every version of Windows has the little network icon in the tray always changing when you transfer data over a network, meaning the screen will be changing pretty much constantly.