I'm trying to make a key event in python. I think that with curses module i can do that but i don't know how to. Please help me.
How can i call a function with a press of a keyboard key. Like, if "space" key is pressed do something, if "c" key is pressed show image, if "s" key is pressed save image. My problem is only to make that key event.
I'm using Linux o.s.
I tried to use urwid module
and when i use this code:
import PIL
import Image
im=Image.open("im.tif")
imshow(im,cmap=cm.gray ,origin=1)
import urwid
def save(input):
if input in ('s'):
savefig("im2.png")
appeared this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 1413, in __call__
return self.func(*args)
File "/usr/lib/pymodules/python2.6/matplotlib/backends/backend_tkagg.py", line 312, in key_press
FigureCanvasBase.key_press_event(self, key, guiEvent=event)
File "/usr/lib/pymodules/python2.6/matplotlib/backend_bases.py", line 1143, in key_press_event
self.callbacks.process(s, event)
File "/usr/lib/pymodules/python2.6/matplotlib/cbook.py", line 163, in process
func(*args, **kwargs)
File "/usr/lib/pymodules/python2.6/matplotlib/backend_bases.py", line 1703, in key_press
self.canvas.toolbar.save_figure(self.canvas.toolbar)
TypeError: save_figure() takes exactly 1 argument (2 given)
What am i doing wrong ? How can i make it work?
ps: I'm sorry for my ignorance but i'm very new in python.
Thank you for answer
Generating a keypress:
On Windows it is quite easy to generate keypresses. On Linux a bit more difficult:
The crude way: os.system('xvkbd -text "\\\\CP" ')
Alternatives:
Simulate keystroke in Linux with Python
Simulating Key Press event using Python for Linux
This module is interesting, uses a kernel module: http://codegrove.org/projects/python-uinput
Couldn't find mention of generating keypress events in curses.
Getting a key press:
Use of curses is a bit much for this case.
Something like: getting a char at a time would be simpler.
Easier than curses would be to use urwid.
Finally, the curses way: http://docs.python.org/release/2.6/howto/curses.html#user-input
Events such as you describe are usually associated with some sort of GUI container (window, canvas, frame, what have you) so "events" really don't have any meaning without some sort of GUI. I could give a more detailed answer if you would say what GUI framework you are using, but barring that, here are links descibing how to handle events using TKInter and WxPython
Related
I have made a simple encryption app, here's the code - https://codeshare.io/ZJ7qJn
But when I press encrypt my tkinter app lags and says Not Responding and so I can't press anything within the tkinter app, but it does complete the encryption process.
Is there any way to make it lag-free?
Try this:
In function encfile replace the call to fiencdone() with:
root.event_generate("<<encryption_done>>")
Add the following new function definitions after the definition of function encfile:
def run_encfile():
from threading import Thread
root.bind('<<encryption_done>>', encryption_done)
Thread(target=encfile).start()
def encryption_done(*args):
fiencdone()
Finally, change line 75 to invoke run_encfile instead of encfile:
file_enc_button = tk.Button(fibutton_frame, text='Encrypt',font='Raleway 15 bold', width=15,command=run_encfile, borderwidth=3)
This will run the encryption in a separate thread but have the call to fiencdone signaling that the encryption is complete done in the main thread, which is required since it updates the GUI.
So, I was just messing around with pyautogui moving the mouse to random positions on the screen, when I manually moved the mouse to the top left corner of the screen and ran the program, it raised a pyautogui failsafe.
I do know how to disable it and all that, but I want to know why is is there in the first place and possible use cases
Code:
import pyautogui
pyautogui.click(x=25, y=1048)
time.sleep(2) # I moved the move to the corner of the screen during this time delay
pyautogui.click(x=701, y=430)
Error:
Traceback (most recent call last):
File "C:\1 Files and Folders\folder\Python Project\Python\CODE\My Projects\Automation.py", line 23, in <module>
job()
File "C:\1 Files and Folders\folder\Python Project\Python\CODE\My Projects\Automation.py", line 18, in job
pyautogui.click(x=1475, y=141)
File "C:\Users\My_user\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pyautogui\__init__.py", line 585, in wrapper
failSafeCheck()
File "C:\Users\My_user\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pyautogui\__init__.py", line 1710, in failSafeCheck
raise FailSafeException(
pyautogui.FailSafeException: PyAutoGUI fail-safe triggered from mouse moving to a corner of the screen. To disable this fail-safe, set pyautogui.FAILSAFE to False. DISABLING FAIL-SAFE IS NOT RECOMMENDED.
According to pyautogui docs
It’s hard to use the mouse to close a program if the mouse cursor is
moving around on its own.
As a safety feature, a fail-safe feature is enabled by default. When a
PyAutoGUI function is called, if the mouse is in any of the four
corners of the primary monitor, they will raise a
pyautogui.FailSafeException.
So simply FailSafe is just thing that if your program just spams the mouse or doing something that you cannot stop it, You can close that in this way, For more information read it docs pyautogui docs
Reset
pyautogui.FAILSAFE = False
at the beginning of ur script.
I have a very basic question related to Python 3. I have started to learn Python but some things are confusing me.
First off, since I want to create a python script that is a GUI, I have imported the tkinter module. The code works in IDLE, but never works when I run it from the terminal. Whenever I run the script from the terminal, I see this traceback error:
Traceback (most recent call last):
File "test1.py", line 9, in <module>
mGui.geometry("geometry 480x480")
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/
__init__.py", line 1607, in wm_geometry
return self.tk.call('wm', 'geometry', self._w, newGeometry)
_tkinter.TclError: bad geometry specifier "geometry 480x480"
Basically, what I am trying to do is create a Python GUI script, save it, and execute it via my terminal whenever I need it.
Here is the code:
#!/usr/bin/env python3
import sys
from tkinter import *
mGui =Tk("")
mGui.geometry("geometry 480x480")
mGui.title("Leilani spelling test")
You don't add the word "geometry" to the argument of the geometry method. Try this instead:
#!/usr/bin/env python3
import sys
from tkinter import *
mGui =Tk("")
mGui.geometry("480x480")
mGui.title("Leilani spelling test")
# You'll want to add this to enter the event loop that causes the window to be shown
mGui.mainloop()
Here are some other GUI configurations that you may need in the future (I personally had trouble finding/applying all the information):
mGui.overrideredirect(1) # Remove shadow & drag bar. Note: Must be used before wm calls otherwise these will be removed.
mGui.call("wm", "attributes", ".", "-topmost", "true") # Always keep window on top of others
mGui.geometry("100x100+500+500") # Set offset from top-left corner of screen as well as size
mGui.call("wm", "attributes", ".", "-transparent", "true") # Remove shadow from window
mGui.call("wm", "attributes", ".", "-fullscreen", "true") # Fullscreen mode
mGui.call("wm", "attributes", ".", "-alpha", "0.9") # Window Opacity 0.0-1.0
I'm still working on my little Tkinter project which is simple a logging console that prints incoming text from the serial line to a Text Widget with some coloring applied.
One question is open and can be found here: Python Tkinter Text Widget with Auto & Custom Scroll
However, even without manual scrolling (so I'm using self.text.yview(END) to auto-scroll to the bottom after inserting text with self.text.insert(END, str(parsed_line)).
The script actually works but every now and then it throws some "silent" exceptions within the Tkinter thread that does not let the whole application crash:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Python26\lib\lib-tk\Tkinter.py", line 2813, in set
self.tk.call((self._w, 'set') + args)
TclError: expected floating-point number but got "0.7807017543859649integer but got "end""
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Python26\lib\lib-tk\Tkinter.py", line 2813, in set
self.tk.call((self._w, 'set') + args)
TclError: invalid command name ".15427224integer but got "end""
It looks as if some method expected a an integer, returns the string integer but got "end" to a method that expected a float which is concatinated with the error message. The float number in that string looks like the position of the scrollbar that I have attached to my text widget:
(...)
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
text = Text(wrap=WORD, yscrollcommand=scrollbar.set)
scrollbar.config(command=text.yview)
text.pack(expand=YES, fill=BOTH)
(...)
I have the feeling that it happens when a lot of lines are inserted within a short time. But since I only have one thread interacting with Tkinter this cannot be a threading issue.
I also got very random errors like that before I had applied the str() function to parsed_line in self.text.insert(END, str(parsed_line)).
This is very strange behavior and I'm wondering if anyone could explain what this is about and how to fix it.
Thanks a lot!
mtTkinter allows multithreading with Tkinter, you can get it here:
http://tkinter.unpythonic.net/wiki/mtTkinter
Just import mtTkinter in place of Tkinter. This will allow you to insert text into a Text widget from multiple threads without conflict. I used it for some instant messaging software I wrote and it works wonderfully.
I need to get focus to a specified window, and the only way I'm seeing on my head, is minimizing all windows on front of it until I get the right one...
How can I do it?
Windows 7, and no specific toolkit....
Every type of window, for example, firefox and console command
You'll need to enumerate through the windows and match the title of the window to get the one you want. The code below searches for a window with "firefox" in the title and sets the focus:
import win32gui
toplist = []
winlist = []
def enum_callback(hwnd, results):
winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
win32gui.EnumWindows(enum_callback, toplist)
firefox = [(hwnd, title) for hwnd, title in winlist if 'firefox' in title.lower()]
# just grab the first window that matches
firefox = firefox[0]
# use the window handle to set focus
win32gui.SetForegroundWindow(firefox[0])
To minimize the window, the following line:
import win32con
win32gui.ShowWindow(firefox[0], win32con.SW_MINIMIZE)
You'll need to enumerate through the windows and match the title of the window to get the one you want. The code below searches for a window with "firefox" in the title and sets the focus
To minimize the window use the following line:
def enumHandler(hwnd, lParam):
if 'firefox' in win32gui.GetWindowText(hwnd):
win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
win32gui.EnumWindows(enumHandler, None)
This works for Windows 10, Python3.5 32bit, pywin32‑223.
I reported the above case, but an error occurred.
Traceback (most recent call last):
TypeError: The object is not a PyHANDLE object
I'm assuming from the question, that you want to write a generic to that can work with any window from any application.
You might want to try the Python Win32 GUI Automation library. I haven't used it but sounds like it might be what you are looking for. If that doesn't work, your best option might be forgo python and use a tool like AutoIt that provides built in support for window manipulation.
If neither of those solutions work you will probable have to directly invoke windows api. I do not know if the win32api package wraps the necessary functionality, otherwise you will have write a python module in c/c++.
If this kind of functionality is available in the .net api, you could use IronPython.