如何弹出屏幕键盘以在 tkinter 的输入小工具中输入一些数据
Posted
技术标签:
【中文标题】如何弹出屏幕键盘以在 tkinter 的输入小工具中输入一些数据【英文标题】:How to pop up an on screen keyboard to enter some data in an entry gadget in tkinter 【发布时间】:2019-07-23 10:07:24 【问题描述】:我有一个 tkinter GUI 应用程序。我正在使用带有触摸屏的树莓派。树莓派的虚拟键盘造成了很多混乱。所以我在想一个自动键盘。有一些输入字段。是否可以做一些事情,比如当用户单击输入字段时,会弹出一个键盘(只是数字),然后用户可以使用该键盘在输入字段中输入值。我只需要从 0 到 9 和 (.) 的数字。甚至可以在 tkinter 中做到这一点吗?有什么建议吗?
import tkinter as tk
root = tk.Tk()
root.geometry('600x400')
container_1 = tk.Frame(root, borderwidth=2, relief="solid")
set_1 = tk.Label(container_1, text = "min Current")
set_1.grid(row=3, column=9)
set_2 = tk.Label(container_1, text = "max Current")
set_2.grid(row=4, column=9)
enter_set_1 =tk.Entry(container_1, width=12) #entry fields, need a keypad here
enter_set_1.grid(row=3, column=10)
enter_set_2 =tk.Entry(container_1, width=12)
enter_set_2.grid(row=4, column=10)
container_1.pack(side="left", expand=True, fill="x", padx=10, pady=10)
root.mainloop()
【问题讨论】:
您必须创建 tk 按钮,然后在用户单击它们时抓取并插入它们的值。要么将按钮固定在主根窗口中的某个位置,要么创建与输入框的绑定,当光标进入条目时生成按钮。 是的,有可能。只需制作一个按钮框架,然后place
在任何你想要的地方。
首先创建带有按钮的框架。接下来,您可以 bind() 到 Entry 函数,该函数将使用 place()
显示此 Frame。这个函数必须获得对 Entry 的引用才能从按钮中放置值——这可能需要更多的工作——但首先你需要带按钮的框架。
【参考方案1】:
这个简单的例子使用Entry
附近的Button
来打开Frame
和keypad
。它还将Entry
分配给变量target
用于将文本放入正确的Entry
。
它使用place
将keypad
放在窗口的中心。
当您单击Entry
并将其显示在Entry
附近时,需要做更多工作才能打开键盘。
使用Class
,您可以创建小部件Keypad
。
import tkinter as tk
def create_keypad(root):
keypad = tk.Frame(root)
for y in range(3):
for x in range(3):
val = y*3 + x
text = str(val)
b = tk.Button(keypad, text=text, command=lambda txt=text:insert_text(txt))
b.grid(row=y, column=x, sticky='news')
x = tk.Button(keypad, text='Hide', command=hide_keypad)
x.grid(row=10, column=0, columnspan=3, sticky='news')
return keypad
def insert_text(text):
target.insert('end', text)
def show_keypad(widget):
global target
target = widget
keypad.place(relx=0.5, rely=0.5, anchor='c')
def hide_keypad():
global taget
target = None
keypad.place_forget()
root = tk.Tk()
root.geometry('600x400')
keypad = create_keypad(root)
target = None
f = tk.Frame(root)
f.pack()
e1 = tk.Entry(f)
e1.grid(row=0, column=0)
b1 = tk.Button(f, text='Keypad', command=lambda:show_keypad(e1))
b1.grid(row=0, column=1)
e2 = tk.Entry(f)
e2.grid(row=1, column=0)
b2 = tk.Button(f, text='Keypad', command=lambda:show_keypad(e2))
b2.grid(row=1, column=1)
root.mainloop()
编辑:我将代码放在 Class 中,所以现在它是小部件。它有“清除”、“退格”和内存“复制”、“粘贴”按钮,但它不使用剪贴板。
import tkinter as tk
# --- classes ---
class Keypad(tk.Frame):
cells = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
['0', '.', '-'],
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.target = None
self.memory = ''
for y, row in enumerate(self.cells):
for x, item in enumerate(row):
b = tk.Button(self, text=item, command=lambda text=item:self.append(text))
b.grid(row=y, column=x, sticky='news')
x = tk.Button(self, text='Backspace', command=self.backspace)
x.grid(row=0, column=10, sticky='news')
x = tk.Button(self, text='Clear', command=self.clear)
x.grid(row=1, column=10, sticky='news')
x = tk.Button(self, text='Copy', command=self.copy)
x.grid(row=9, column=0, sticky='news', columnspan='3')
x = tk.Button(self, text='Paste', command=self.paste)
x.grid(row=9, column=10, sticky='news')
self.label = tk.Label(self, text='memory:')
self.label.grid(row=8, column=0, columnspan=11, sticky='news')
x = tk.Button(self, text='Hide', command=self.hide)
x.grid(row=10, column=0, columnspan=11, sticky='news')
def get(self):
if self.target:
return self.target.get()
def append(self, text):
if self.target:
self.target.insert('end', text)
def clear(self):
if self.target:
self.target.delete(0, 'end')
def backspace(self):
if self.target:
text = self.get()
text = text[:-1]
self.clear()
self.append(text)
def copy(self):
#TODO: copy to clipboad
if self.target:
self.memory = self.get()
self.label['text'] = 'memory: ' + self.memory
print(self.memory)
def paste(self):
#TODO: copy from clipboad
if self.target:
self.append(self.memory)
def show(self, entry):
self.target = entry
self.place(relx=0.5, rely=0.5, anchor='c')
def hide(self):
self.target = None
self.place_forget()
# --- main ---
root = tk.Tk()
root.geometry('600x400')
keypad = Keypad(root)
f = tk.Frame(root)
f.pack()
e1 = tk.Entry(f)
e1.grid(row=0, column=0, sticky='news')
b1 = tk.Button(f, text='Keypad', command=lambda:keypad.show(e1))
b1.grid(row=0, column=1, sticky='news')
e2 = tk.Entry(f)
e2.grid(row=1, column=0, sticky='news')
b2 = tk.Button(f, text='Keypad', command=lambda:keypad.show(e2))
b2.grid(row=1, column=1, sticky='news')
root.mainloop()
【讨论】:
很酷的解决方案。将 9 和 (.) 添加到上述解决方案中。尝试实现退格和一些验证方法。非常感谢。 对于退格,您必须从条目中获取全文,从文本中删除最后一个字符,清除条目并将完整的新文本放入条目中。 验证您可以直接分配给Entry
,您不必更改键盘。一些有验证但没有描述的例子:furas/python-examples/tkinter/validate
在 GitHub 上,我将所有代码都放在了 Class 中,所以现在它是小部件。它还有“清除”、“退格”和内存“复制”、“粘贴”按钮,但它不使用剪贴板。 furas/python-examples/tkinter/keypad【参考方案2】:
#method to add backspace button to above solution
backspacebtn= tkinter.Button(keypad, text='Back', command=lambda:fn_back())
backspacebtn.grid(row=1, columnspan=1)
def fn_back():
global target
val = target.get()
new_val= val[:-1]
target.delete(0,tk.END)
target.insert(0,new_val)
【讨论】:
这不回答任何问题。请在回答时详细说明。检查这个***.com/help/how-to-answer @mchawre '这不回答任何问题':这并不完全正确......还有一个(甚至很短的)仅代码回答isn't considered very low quality...以上是关于如何弹出屏幕键盘以在 tkinter 的输入小工具中输入一些数据的主要内容,如果未能解决你的问题,请参考以下文章