I'm trying to track the window focus changes (what application is in the foreground) with python 3.7 in a windows 10 (64b) machine because I'd like to log how much time I spend using each application (I hope chrome is a different app for each tab XD)
I tried to search in the web about how to do it but didn't find it (odd). For now I learnt that I have to install win32api (pypiwin32) and that with this code I can get the name of the window
from win32gui import GetWindowText, GetForegroundWindow
print(GetWindowText(GetForegroundWindow()))
That works fine but I don't want to make a loop with that every second, I'd like to have a callback that when the event 'onWindowFocusChange' or something like that is called run that.
EDIT: As David Heffeman pointed out, I was using wrong terminology. What I meant is the piece of software that I'm interacting with at each point. (None if the screen is blocked, If I'm playing a game and listening to music, the game, if I'm reading a web or a pdf that browser or reader, etc... hope this clarifies the matter.
This example code here logs all focus changes: https://gist.github.com/keturn/6695625
Related
How can I send keystrokes and mouse movements to a specific running program through its PID. I've used both pywinauto and pynput, and they work great, but I want to send keys to a program that is not in focus. I found this question: How to I send keystroke to Linux process in Python by PID? but it never explains what filePath is a path to.
If you could help solve for this example, that would be great! I want to send the "d" key to an open Minecraft tab for 10 seconds, and then send the "a" key for the next 10 seconds and stop. I would need this to be able to run in the background, so it could not send the keys to the computer as a whole, but only to the Minecraft tab. I am on Windows 10 by the way.
Any help would be appreciated!
Pretty sure you won't be able to, at least not easily let me explain a little bit how all of this works.
Lets start with the hardware and os, the OS has certain functions to read the input you give the computer. This input goes into a "pipe", the OS is reading input, and putting into the pipe, on the other side of the pipe there may be an application running, or it may not. The OS typically manages this (which app to put on the pipe listening) by defining which app/window is active. Apps access this pipe with the API given by the OS, they read the input and decide on it.
The libraries you cited above, change the values of the keyboard and mouse, in other words, they make the OS read other values, not the real ones, then the OS puts them in the "pipe", and are read by the app that is listening on the pipe (the one active). Some apps have their own API's for this, but I would guess Minecraft doesn't. If they don't have an API, what can you do? well, as I said, nothing easy, first of all "hacking" the app, in other words change it to listen to some other input/output rather than the one given by the OS, (this would be you making your own API). The other one would be you changing the OS, which would also be extremely hard, but maybe a tiny bitty easier. It also depends on your OS, I think Microsoft does offer input injection api's
So, simple options, first, run a VM with a GUI and use pywinauto, pyautogui, etc. The other option would be if you can run it in the browser, do so, and use something like Selenium to automate the input.
Quick note, why does selenium works and the browser can read input in the background? Easy, it's not, it just executes the code it would execute if it would have read the input! javascript, cool isn't
With ahk you can do this with Python+AutoHotkey
pip install ahk
pip install "ahk[binary]"
from ahk import AHK
from ahk.window import Window
ahk = AHK()
win = Window.from_pid(ahk, pid='20366')
win.send('abc') # send keys directly to the window
Note that some programs may simply ignore inputs when they are not in focus. However, you can test this works in general even when not in focus by testing with a program like notepad
Full disclosure: I author the ahk library.
After my kivy app is pushed to my android device through buildozer,
First I can see Kivy loading symbol,then screen is blank for 30 seconds. after that my app is getting opened.
And this is happening on first run as well as subsequent runs.
I have read some answers and got to know that "we can avoid this problem by starting with minimal GUI
and loading the rest more lazily".
Could any one please let me know,how we can load like this when the app opens?
For an example, if you used on_pre_enter function and if you give this function to do many things, its normal you to wait much a time. But there is a no any code so i can't analyze your code and give any tip.Your computer's and android's processing time depends on background applications, hardware and many things does that. So try to share your minimal code just like your starting functions or you can create minimal application which has these functions so you can test your codes partly.
I spent the last hours trying to get to know wxPython, because I want to write a GUI program. I found some tutorials on that (not too many), but all of them just explain how to add yet another kind of widget, down to fancy things like LED number outputs and mouse gestures (this one e.g. takes it quite far: Another Tutorial). But everything I could find so far does nothing more than create a static GUI, waiting for the user to do something, then execute some handlers and wait again. It took me a while to even find out that wx.App takes a part in all of that, and that you can subclass it.
I want to write a program, that does things without input! The GUI is supposed to be a client that logs in on a server, and when the server sends something, I want the GUI to show what happened. I could not find a single tutorial even mentioning, that such programs exist. How can I write such a thing? How do they integrate with wxpython?
Do I need to span another thread? Is there a way to hook into the MainLoop and have some code executed periodically, that checks for change and then updates some of those fancy GUI things? And is there any page that teaches you, how to do this?
First of all, you should figure out how to do what you want WITHOUT a GUI. In this case, you'll need to figure out how to login to a server. You'll probably need to use something like paramiko for that. See http://www.lag.net/paramiko/
Once you've got that figured out, then you can add it to your GUI. Probably in a button handler so when the user presses a button, it pops up a dialog asking for a user name and password to pass to paramiko to login to the server.
If the server query takes a long time to execute (like say you're querying a database for a huge set of data), then you'll want to run the query in a separate thread. Why? Because that query will block the GUI's main loop and make your app freeze until it finishes. See the following articles for information on wxPython and threads:
http://wiki.wxpython.org/LongRunningTasks
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
I wrote up a tutorial on making wxPython talk to a socket server, so you might find that useful: http://www.blog.pythonlibrary.org/2013/06/27/wxpython-how-to-communicate-with-your-gui-via-sockets/
I also have an article on how to make an image viewer, and do CRUD ops to a database on there.
Using tk in my multi-threaded(*) console application causes it to crash without stacktrace, giving the message "Tcl_WaitForEvent: Notifier not initialized Abort trap".
The symptoms were that all my program's functions worked fine, until I brought up the tk window - then the very next operation would cause the crash.
Immediate searching found that Tkinter is not safe with respect to Python threads, so I made sure that I was not calling any Tk functions anywhere other than my main thread. The crashes continued.
I lost several hours because I believed that it was the specific command I was using that crashed the program - but eventually I realized that any keyboard input would crash the program.
After a lot of debugging, I finally boiled it down to a small program that demonstrates the issue, exposing what I believe is a bug or certainly a feature that needs documentation in the Tkinter library.
I was working on this posting I was debugging. I'm going to post it and answer my own question in the hopes that it will prevent the next person from wasting a day on it.
--
(* - Yes, it certainly needs to be multi-threaded. I have a thread for my socket connection, a thread that listens to a mic and finds levels, a thread to drive my serial port and more. In each case, the thing I'm reading on the thread naturally blocks most of the time.)
The solution!
The issue is that tk crashes if you read from Python's raw_input in a different thread from the tk thread!
A small program demonstrating the issue is here. If you run it, it gets keyboard input perfectly happily from the second thread - until you enter the command "tk" when it brings up an empty tk window. You can do whatever you like with that window - until you type in the console window and press return, when the whole program crashes.
Why am I reading from raw_input in a thread that isn't the main thread?
My program is a console application, but I'm controlling a lot of different parts, one of which is the pi3d OpenGL ES 2.0 graphics library which must be updated at or near the frame rate from the main Python thread.
How to work around it?
"Simple" enough - register for tk menu events and just get the keys directly! Except that's a crappy solution, because you have to emulate all those things that the console does for you already - deleting, left and right arrows and that sort of thing. But that's what I'll have to do.
Should the program become a fully-fledged tk application?
But I can't do that - the whole point of this program is that you can run it through a terminal window - often sshing into headless machines. I'm frankly more likely to make it a curses program!
The tk window is a minor part of the whole thing - just a window to show emulated lights when developing if you don't have the hardware hooked up (or don't want to keep flashing yourself in the face). I won't try to bring it up on headless machines, and that's fine.
Is this a bug?
I'm always loathe to attach such a label to software not my own, but I'm hard-pressed to come up with any other description. It causes a crash, and that crash produces no useful information of any type. I consider that Tkinter is somewhat lame for simply crashing when called from different threads, but at least this behavior is documented (if you dig down a little) - in this case, I'm calling a Python built-in, so I have no basis to expect that it will interact with this library at all, and there's no documentation of this problem.
Could there be a workaround?
I'm sort of hoping there will be a work-around - this one-page program was a single item on a long list of features has turned into a full-day head-scratching debugging session and I don't want to have to throw another day at least after this when none of this time is actually producing new features.
The best thing is if the tk team admitted this was a bug and came up with a fix. But I wouldn't expect that at my desktop before a year from now...
So perhaps the real best thing would be if there were some way to get tk to simply ignore the keyboard, and not crash. I did a tiny experiment with tk's "busy" but that didn't work and just doesn't seem to be the right sort of thing.
A little later, I'm now thinking about running the lighting as an independent program, a separate subprocess using Python's Subprocess library, and sending it text commands through stdin. This would be overkill if this were the only problem that was being solved, but in fact
Got it.
Replacing raw_input() with sys.stdin.readline() did the trick - at least in the demo (which I updated). Feel free to download this and experiment with it yourself!
I hope this saves someone else the time.
In my case (as mentioned in the comments under #Tom Swirly's answer) the solution was to switch to a non-interactive backend:
import matplotlib
matplotlib.use('Agg')
I am new to Python and am trying to send a combination of key strokes to an application I open under Windows 7. While my script will work flawlessly when I invoke Notepad.exe for testing purposes, it does not with the actual application I am trying to use.
Here is my code so far:
import win32com.client
import time
import SendKeys
import os
from ctypes import *
shell = win32com.client.Dispatch("WScript.Shell")
os.startfile("C:\...exe")
time.sleep( 5 )
shell.SendKeys('%{F4}') # 'Alt+F4' to close the application again.
For some reason, the application does not close in reaction to the script. When I hit 'Alt + F4' on my keyboard, it closes as expected. Any ideas on what might be going on here?
Any help is welcome! Please bear in mind that I am new to Python ;-)
PS: I have already verified that the application runs in the active window by including this code snippet:
import win32ui
wnd = win32ui.GetForegroundWindow()
print wnd.GetWindowText()
OK ... I rebooted the system and for some reason it is working now. I am wondering if some process instance from previous programme invocations might have been lingering on the system. Anyway, I am now able to perform the manipulations as expected, even if I don't really understand what went wrong in the first place.
Thanks to everyone who took the time to repsond.
I know this was asked 6 years ago, but someone might be with the same problem, so here is a possible solution:
shell.AppActivate('Put_The_Name_Here')
The code above will select the program, file, etc that is opened but not activated, that, maybe, is your problem.
Hope this helps someone!