如何弹出屏幕键盘以在 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来打开Framekeypad。它还将Entry 分配给变量target 用于将文本放入正确的Entry

它使用placekeypad 放在窗口的中心。

当您单击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 的输入小工具中输入一些数据的主要内容,如果未能解决你的问题,请参考以下文章

小程序键盘的自动弹出和收起

如何通过按下按钮从 tkinter 输入字段返回变量以在另一个函数中使用?

(vue)移动端点击输入框,弹出键盘,底部被顶起问题

弹出虚拟键盘时如何在 iOS 浏览器上重新定位视图?

搜狗输入法表情太小了怎么办

Android 点击输入框弹出键盘,布局随键盘往上移动