How can I use win32gui in order to have an app run in the background? - pywin32

I was able to find a great piece of code from here on how to create a Tray app using the win32gui module.
However, that app runs based on a function called notify which only runs when the mouse is moving over the icon.
How can I make the app do something constantly in a loop, regardless of what the user does?
(In other words, I want to use win32gui in a non-event-based way.)

Instead of using win32gui.PumpMessages (which runs its own loop) in the code, replace it with the following loop:
while True:
your_function()
win32gui.PumpWaitingMessages()
This will allow you to run your own functions in the program loop.

Related

Running one Autokey script from another Autokey script?

Right now I've got two Autokey scripts (for modularity), one that opens a file, and one that puts text in it.
The one that opens the file has hotkey F1 (and we'll call this script 1 for simplicity), and the one that puts text in it has hotkey F2. I want a new Autokey script, that when I hit F3, it runs both the 1 script and the 2 script.
I've tried making the 3 script just send the F1 and F2 keys, but the timing is all off. It would be better if I could just call 1 and 2 from 3. Is this possible?
Thanks!
https://github.com/autokey/autokey/blob/fc7c6b90f3f28a57ad256829ef2b69e3be5148d2/lib/autokey/scripting.py#L1242
engine.run_script("<description>")
ought to do the trick
"Description" in this context is generally the name of the script in the side bar in the AutoKey interface. If you open up the .json file for the script you can see it for sure, but it will be the name displayed in the side bar unless you have duplicate names for scripts in the same folder or some other edge scenario
AutoKey is not recursive. It does not inspect the output of an AutoKey phrase or script to look for hotkeys or trigger abbreviations which would invoke further actions. That's why your initial solution does not work.
It depends on what you're actually trying to do.
If you have multiple independently useful scripts, the best approach is the one #Icallitvera offers.
If you just want to modularize shared functionality, you can create Python modules of functions and place them in the AutoKey Modules directory. Then, you can import them into any AutoKey script which needs them.
You can find/set the Modules directory from the AutoKey Main Menu via Settings->Configure AutoKey->Script Engine.
At the moment, this approach is limited because scripts invoked this way do not (easily) have access to the AutoKey API, so they can't include any API calls. We plan to fix this in the next major release, AutoKey 0.96. If you really need to do that now, ask on our support list or on Gitter.
I ran into that same problem and the only way I found to work around that restriction is by using the exec() function. Since the scripts with functions to share were already in the AutoKey user folder I used that. So in order to load shared functions of my user module "mygame" into the autokey script I used:
exec(open(engine.configManager.userCodeDir + "/" + "mygame.py").read())
To avoid name collisions when "importing" more than one script and a more module-like feeling I put the functions in classes and instantiate with a variable that is named like the module.
So in the end it looks like this:
mygame.py:
import time
class MyGame:
def GameReload(self):
self.GameExitNoSave()
time.sleep(0.3)
self.GameLoadCurrent()
def GameExitNoSave(self):
keyboard.send_key('d')
time.sleep(0.1)
keyboard.send_key('<up>')
time.sleep(0.05)
keyboard.send_key('<enter>')
def GameLoadCurrent(self):
keyboard.send_key('<down>')
time.sleep(0.1)
keyboard.send_key('<down>')
time.sleep(0.1)
keyboard.send_key('<enter>')
time.sleep(0.5)
keyboard.send_key('<enter>')
mygame = MyGame()
User script in AutoKey:
exec(open(engine.configManager.userCodeDir + "/" + "mygame.py").read())
mygame.GameReload():

wxPython: How to Show status/progress window and update the progress from another python code?

I have a regular python app (not wx) , and i want to add a wxStatusWindow (Guage Class) in order to show the progress in my App.
There are many examples in web for wxGuage /Status windows but in all examples the progress is handled within the wxFrame.
How can i call the statusWIndow from my python code while the python code is running ?
I did some reading...is it running on separate thread??
I will appreciate an example...how can i do that?
alternatively..I though of just opening a wxDialog from my app and showing info about the progress (and than closing it and raising another wxDialog with new info)...but again..
I need the message to be displayed and in parallel the code in my app to continue running..and than to be able to close the message box from my python app
any Idea's?
code examples?
10x
Yodash

How to, in Python, ignore certain/all keypresses while function executing in program on Macintosh

I would like to know, how would I, in Python, be able to ignore certain/all keypresses by the user while a certain function in the program is executing? Cross platform solutions are preferred, but if that is not possible, then I need to know how to do this on Macintosh. Any help is greatly appreciated! :)
EDIT: Right now, I am processing keypresses through the turtle module's onkey() function since I did create a program using turtle. I hope this helps avoid any confusion, and again, any help is greatly appreciated! :)
You might want to modify your question to show how you're currently processing key-presses. For example is this a command-line program and you're using curses?
You could use os.uname to return the os information or sys.platform, if that isn't available. The Python documentation for sys.platform indicates that 'darwin' is returned for OSX apple machines.
If the platform is darwin then you could, in your code, ignore whatever key-presses you want to.
Edit (Update due to changed question):
If you want to ignore key-presses when a certain function is being called you could either use a lock to stop the key-press function call and your particular function being executed together.
Here is an example of using a lock, this may not run, but it should give you a rough idea of what's required.
import _thread
a_lock = _thread.allocate_lock()
def certainFunction():
with a_lock:
print("Here's the code that you don't want to execute at the same time as onSpecificKeyCall()")
def onSpecificKeyCall():
with a_lock:
print("Here's the code that you don't want to execute at the same time as certainFunction()")
Or, depending on the circumstances, when the function which you don't want interrupting with a key press is called, you could call onkey() again, with the specific key to ignore, to call to a function that doesn't do anything. When your particular function has finished, you could call onkey() again to bind the key press to the function that processes the input.
I found similar problems, maybe it will help you with your problem:
globally capture, ignore and send keyevents with python xlib, recognize fake input
How do I 'lock the keyboard' to prevent any more keypresses being sent on X11/Linux/Gnome?
https://askubuntu.com/questions/160522/python-gtk-event-ignore

Is it possible to incorporate an environment variable into a ruby script for Calabash?

I am testing a feature on an app that requires the user to be a certain age. The only time you see the prompt that asks for your age is once you open the app for the first time and once you log out of the app. I don't want my test to only go through my steps to log in and then log out to be able to see this prompt, but I also don't want to manually reset the data in between tests either. Isn't this why we write scripts? Anyways, before I launch the test, I use the environment variable RESET_BETWEEN_SCENARIOS=1 cucumber features/my_feature.feature. Is there a way that I can use this variable INSIDE of my step definition so that it resets the data on its own once I run the script?
I'm not familiar with Calabash, but it appears to be using cucumber. If that is the case, you could handle the action in a before or after hook which would run before or after each scenario.
Within the features/support folder, add a file hooks.rb
Before() do
if ENV['RESET_BETWEEN_SCENARIOS'] == '1'
#code to reset data
end
end
This could also be run after the scenario by using After() do. The same if/then could be used within a scenario step as well.

Application to accept arguments while running

I am using visual studio 2008 and MFC. I accept arguments using a subclass of CCommandLineInfo and overriding ParseParam().
Now I want to pass these arguments to the application while running. For example "test.exe /start" and then to type in the console "test.exe /initialize" to be initialized again.
is there any way to do that?
Edit 1: Some clarifications. My program starts with "test.exe /start". I want to type "test.exe /initialize" and initialize the one and only running process (without closing/opening). And by initialize I mean to read a different XML file, to change some values of the interface and other things.
I cannot think of an easy way to accomplish what you're asking about.
However, you could develop your application to specifically receive commands, and given those commands take any actions you wanted based upon receiving them. Since you're already using MFC, you can do this rather easily. Create a Window (HWND) for your application and register it. It doesn't have to be visible (this won't necessarily make you application a GUI application). Implement a WndProc, and define specific messages that you will receive based on WM_USER + <xxx>.
First and obvious question is why you want to have threads, instead of processes.
You may use GetCommandLine and CommandLineToArgvW to get the fully formatted command line. Detect the arguments, and the call CreateProcess or ShellExecute passing /watever to spawn the process. You may also want to use GetModuleBaseName to get the name of your own EXE.

Resources