When pyautogui.prompt() is called it displays a message box and it's always in the same spot. That box covers pictures I need to see, so I can write the right number. I need to move the box or make it invisible or minimize it or make it out of focus.
The problem is that you can't execute code while or after the message box is showing. The pyautogui.prompt is coded like this: pyautogui.prompt(text='', title='', default='', root=None, timeout=None). I know what each argument does, except root. The root argument doesn't accept boolean, integers, lists, strings, Point or tuple. It displays an error message: AttributeError: 'tuple' object has no attribute 'withdraw', if you put boolean, integers, lists, strings, Point or tuple in.
The only thing that root accepts is pyautogui.moveTo, pyautogui.dragTo and other mouse commands. Which are not that useful, because they execute before the box appears. Here is my code:
import pyautogui
selected_picture = int(pyautogui.prompt('Please write which picture to click on.',
'Select picture'))
if selected_picture == 1:
pyautogui.click(500,270)
if selected_picture == 2:
pyautogui.click(700,270)
if selected_picture == 3:
pyautogui.click(900,270)
Yes, I need to do it with pyautogui.prompt or some other message box. The original documentation doesn't even mention the root or timeout attribute and I can't find that information anywhere. I was trying something with tkinter, but I have no idea what it does.
I don't know if you want to change where the window appears or if you want to move it after it appears. If you just want to change the default window location, that can be done by importing pymsgbox and changing its rootWindowPosition value (the default value is "+300+200") and then every message box you put after that will appear at the new location.
import pyautogui as pag
import pymsgbox
pag.prompt(text="300,200") # appears at (300, 200)
pymsgbox.rootWindowPosition = "+500+500"
pag.prompt(text="500,500") # appears at (500, 500)
I couldn't find a way to move the prompt, so I did something easier. I just used IDLE.
import pyautogui
pyautogui.hotkey('alt','shift')
selected_picture = input()
pyautogui.hotkey('alt','shift')
if selected_picture == 1:
pyautogui.click(500,270)
if selected_picture == 2:
pyautogui.click(700,270)
if selected_picture == 3:
pyautogui.click(900,270)
Related
I would like to know how to get user input in python without using the command line or an input box.
Let me explain. I do not want to do this
#All code is python 3
name=input("What is your name?")
Why? When running scripts, the command line is not auto-focused. Furthermore, it pops up another window, something I do not want because I can't hit escape to close it in a hurry (Something which you may want to do if you're playing a game).
What have I tried?
I looked at WX and it's dialog function, something like this:
import wx
app=wx.App()
def text_entry(title,message):
result=None
dlg=wx.TextEntryDialog(None, message,title)
if dlg.ShowModal()==wx.ID_OK: result=dlg.GetValue()
dlg.Destroy()
return result
text_entry("Text entry","Enter something here")
While this works, it pops up another window which again, I do not want. However, it is closer to what I am ultimately looking for, because I can hit escape to make it go away.
I have tried using pygame and it's key.get_pressed() function, but it inserts a lot of the same letter into the entry, even if I gently tap the key. Also, when I implemented it into the project, it can only pick up on normal letters. Writing 26 if statements to detect key presses for a single letter with or without the shift key seems a little counter intuitive.
Finally, I am a bit hesitant to try tkinter. I happen to be blind, and from what I read, tk is very visual, which makes me concerned that it won't play nicely with my screen reader (NVDA).
So, I'm here. After searching on google for "getting input without using command line in python 3", "input in the same window", and "input without using input()" yielded nothing.
To recap, I want to accept user input without using the input() function, and without any additional windows popping up for the duration of me doing so.
Thank you.
What about this solution using the msvcrt module. At any time if you press escape then the program will exit. Python sys.exit(), and built-ins exit() and quit() all call raise SystemExit so this is just one less call to perform. If you press the enter or return key then the while loop ends and you can use the keys that were pressed later in your program as they are stored in the variable user_input. The print at the end just proves that the pressed keys are stored in user_input variable and the input() function simply to leave the window open so you can see it working.
import msvcrt
user_input = b''
while True:
pressed_key = msvcrt.getche() # getch() will not echo key to window if that is what you want
if pressed_key == b'\x1b': # b'\x1b' is escape
raise SystemExit
elif pressed_key == b'\r': # b'\r' is enter or return
break
else:
user_input += pressed_key
print('\n' + user_input.decode('utf-8')) # this just shows you that user_input variable can be used now somewhere else in your code
input() # input just leaves the window open so you can see before it exits you may want to remove
So after doing some more research, I found this:
https://codeload.github.com/Nearoo/pygame-text-input/zip/master
I think this is what I am looking for, though it still needs to be slightly modified. Thank you for the assistance
According to the documentation, filedialog.askopenfilename() is supposed to return an empty string if the user clicks "Cancel," but it's not doing that, and I can't figure out what it's actually returning.
I made this little test program, and the behavior is identical to my actual project:
from tkinter import *
from tkinter import filedialog
name = filedialog.askopenfilename()
if name == '':
print("Nothing chosen")
else:
print(name)
What ends up printing when the user clicks cancel is a pair of empty parentheses ()
Replacing '' with '()' does not change anything.
Any help figuring out what is happening is appreciated. Thank you.
UPDATE: Got it working thanks to #PaulRooney's suggestion, but now, the first time I run this section of code (in my full project), it returns the empty tuple. For every subsequent run, it returns an empty string.
Simply checking for both works for what I need, but it's bizarre behavior.
I'm using Python 3 on Linux Mint.
if name will work just fine.
from tkinter import *
from tkinter import filedialog
name = filedialog.askopenfilename()
if name:
print(name)
else:
print("Nothing chosen")
Didn't see this post till after I answered an older but similar question!
Basically, clicking Cancel will return an empty string...
Unless you actually select/highlight a file first and then click cancel.
This seems to return an empty tuple!!!
(I didn't try with initialdir and initialfile options but am guessing they also cause an empty tuple to be returned... at least initially?)
Using python 2.6.6 (IDK, ask RedHat)
Running the following code produces the subsequent results
f_picked = tkFileDialog.askopenfilename()
test = type(f_picked)
print (test)
Results:
<type 'unicode'> # Nothing selected, Cancel clicked
<type 'tuple'> # File selected, Cancel clicked
<type 'str'> # File selected, OK clicked
<type 'tuple'> # Multiple files selected, OK clicked
I have a File -> Open menu item that displays an askopenfilename dialogue. I am finding that with python 2.7 and 3.6, the first time I use the dialogue and select Cancel or close the dialogue from the window border, it returns an empty tuple instead of ''. Every time thereafter the dialogue returns '' on Cancel or window close.
Perhaps this is some sort of feature but it feels like a bug, particularly for this dialogue that doesn't support selection of multiple files. An empty tuple would make sense from askopenfilenames.
I've settled on this simple test and cleanup for the file name returned by the askopenfilename dialogue:
if str(filename) == '()':
filename = ''
I'm using python 3.8 and from my experience
filedialog when is closed does not always return an empty string, to handle it you can use the type keyword to identify the type of data from filedialog and then use the if statement to handle it
from tkinter import filedialog
filePath = filedialog.askopenfilename()
if str(type(filePath))=="<class 'tuple'>" or filePath == '':
# This part will be executed when the user cancels or exit
print('filePath is not contain path')
else:
print('your path',filePath)
Hmm... Make sure you are using using Python 3 because this won't work on Python 2
It worked for me, when I changed the brackets to "" (i'm on Python 2)
I'm trying to make a trigger for the Ok button in my application
The current code I tried was this:
self.okPushButton.setShortcut("ctrl+Enter")
However, it doesn't work, which kind of makes sense. I tried looking up some key sequences here, but, again, a similar issue if I try with the shift or alt keys.
How can I trigger the OkButton with ctrl+Enter
According to the docs:
Qt.Key_Enter 0x01000005 Typically located on the keypad.
That is to say when you set Enter we refer to the key that is on the numeric keypad.
But if you want to use the default enter you must use Return.
self.okPushButton.setShortcut("Ctrl+Return")
# seq = QKeySequence(Qt.CTRL+Qt.Key_Return)
# self.okPushButton.setShortcut(seq)
I'm quite new to Python and have been unsuccessful in finding a way around this problem. I have a GUI using TKinter that displays an image using Label. I would like the user to be able to click on two places in the image and use those two pixel locations elsewhere.
Below is the basic code I'm using so far, but I'm unable to return the pixel locations. I believe bind is not what I want to use, is there another option?
px = []
py = []
def onmouse(event):
px.append(event.x)
py.append(event.y)
return px,py
self.ImgPanel.bind('<button-1>',onmouse)
If I try to use:
px,py = self.ImgPanel.bind('<button-1>',onmouse)
I get an error "Too many values to unpack"
bind is what you want, if you want to capture the x,y coordinate of the click. However, functions called from bindings don't "return". Technically they do, but they return a value to the internals of Tkinter.
What you need to do is set an instance or global variable within the bound function. In the code you included in your question, if you add global px,py, you can then use those values in other code.
I have a (single line) TextCtrl. The user types data into this. When they press enter, the contents of the box need to be extracted so they can be processed. I can't figure out how to catch enter being pressed.
According to the docs, with the style wx.TE_PROCESS_ENTER set on my TextCtrl, it should generate a wx.EVT_COMMAND_TEXT_ENTER event when enter is pressed in the box, which I could then catch. However, wx.EVT_COMMAND_TEXT_ENTER seems not to exist (I get "module has no attribute EVT_COMMAND_TEXT_ENTER), so I'm a bit stuck. Googling just gets a couple of hits of people complaining wx.EVT_COMMAND_TEXT_ENTER doesn't work, so I guess I need another way of doing it.
I've never seen wx.EVT_COMMAND_TEXT_ENTER. I have used wx.EVT_TEXT_ENTER though...
Use style = wx.TE_PROCESS_ENTER in TextCtrl and Bind with Event wx.EVT_TEXT_ENTER
self.Text_Enter = wx.TextCtrl(self , 2 ,style = wx.TE_PROCESS_ENTER, size =(125,150), pos = (170,0))
self.Text_Enter.SetForegroundColour(wx.RED)
self.Bind(wx.EVT_TEXT_ENTER, self.Txt_Ent, id = 2)
def Txt_Ent(self,event):
msg1 = (str(self.Text_Enter.GetValue()))
wx.MessageBox(msg1)