如何使用触摸屏显示调用和关闭 Tkinter 制作的虚拟键盘 [英] How to call and close a virtual keyboard made by Tkinter using touchscreen display

查看:43
本文介绍了如何使用触摸屏显示调用和关闭 Tkinter 制作的虚拟键盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在打开和关闭使用 Tkinter 制作的虚拟键盘时遇到问题.我正在创建一个 GUI,用户将使用触摸屏显示器浏览它,并且用户需要输入条目.

我尝试了 var_name.bind('FocusIn', callback) 来调用虚拟键盘和 var_name.bind('FocusOut',callback) 来关闭虚拟键盘,但是当我同时使用虚拟键盘时,它会立即打开然后关闭.

我希望你们能帮助我这是我的代码:

导入 tkinter 作为 tk定义选择(条目,值,事件):focused_entry.insert("end", 事件)pyautogui.press(事件)全局大写大写 = 错误如果值==空格":值 = ' 'elif 值 == '回车':值 = '\n'elif 值 == 'Tab':值 = '\t'如果值==退格":如果 isinstance(entry, tk.Entry):entry.delete(len(entry.get())-1, 'end')#elif isinstance(entry, tk.Text):其他:# tk.Textentry.delete('end - 2c', 'end')('Caps Lock', 'Shift') 中的 elif 值:uppercase = not uppercase # 将 True 改为 False,或 False 为 True别的:如果大写:值 = value.upper()entry.insert('end', value)返回定义创建(根,条目):字母 = [['`','1','2','3','4','5','6','7','8','9','0','-','=','退格'],['Tab','q','w','e','r','t','y','u','i','o','p','[',']',"\\"],['Caps Lock','a','s','d','f','g','h','j','k','l',';',"'",'进入'],['Shift','z','x','c','v','b','n','m',',','.','/','Shift'],['空间']]全局窗口窗口 = tk.Toplevel(root)window.configure(background="cornflowerblue")window.geometry("+0+483")window.wm_attributes("-alpha", 0.7)对于 y, enumerate(alphabets) 中的行:x = 0#for x, enumerate(row) 中的文本:对于行中的文本:如果文本在 ('Enter', 'Shift'):宽度 = 18列跨度 = 2elif 文本 == '空格':宽度 = 124列跨度 = 16elif 文本 == '退格':宽度 = 10列跨度 = 1elif 文本 == '\\':宽度 = 10列跨度 = 1elif 文本 == 'Tab':宽度 = 10列跨度 = 1elif 文本 == '`':宽度 = 10列跨度 = 1elif 文本 == '大写锁定':宽度 = 10列跨度 = 1别的:宽度 = 4列跨度 = 1tk.Button(window, text=text, width=width,命令=拉姆达值=文本:选择(条目,值),padx=3, pady=3, bd=12, bg="black", fg="white", takefocus = False).grid(row=y, column=x, columnspan=columnspan)x+= 列跨度#  - - 主要的  - -定义记住_焦点(事件):全局focused_entryfocus_entry = event.widget如果 __name__ == '__main__':根 = tk.Tk()root.title('测试键盘')label = tk.Label(root, text='测试键盘')label.grid(row=0, column=0, columnspan=2)entry1 = tk.Entry(root)entry1.grid(row=1, column=0,sticky='news')entry1.bind("", remember_focus)entry2 = tk.Entry(root)entry2.grid(row=2, column=0,sticky='news')entry2.bind("", remember_focus)text1 = tk.Text(root)text1.grid(row=3, column=0,sticky='news')text1.bind("", remember_focus)root.mainloop()

感谢@furas 先生帮助我创建虚拟键盘.我编辑了代码并在此处尝试了 Bryan Oakley 的回答 Tkinter 检查哪个条目最后具有焦点

解决方案

问题:使用触摸屏调用并关闭虚拟键盘

代替调用和关闭,实例化你的虚拟键盘一次并使用Toplevel方法.deiconify().withdraw().

不要将事件 '' 绑定到每个输入小部件,使用 bind_all(... 绑定到 应用程序级别>.


参考:


核心点:

  • 使用 .bind_all('', ....deiconify()
  • 使用 .bind_all('', ....withdraw()

# VKeyboard.py将 tkinter 作为 tk 导入类 VKeyboard(tk.Toplevel):def __init__(self, parent):super().__init__(parent)# 不要在实例化时显示Toplevel"超级().withdraw()自我创建()# 处理所有应用==父事件parent.bind_all('', self.on_event, add='+')parent.bind_all('', self.on_event, add='+')def on_event(self, event):w = event.widget# 不处理自己的Button如果 w.master 不是自己:w_class_name = w.winfo_class()如果 w_class_name 在 ('Entry',):如果 self.state() == '撤销':self.deiconify()self.entry = welif w_class_name in ('Button',):超级().withdraw()w.focus_force()定义创建(自我):# 定义虚拟键盘​​`tk.Button`经过

<块引用>

使用

导入 tkinter 作为 tk从 VKeyboard 导入 VKeyboard类信息亭(tk.Tk):def __init__(self):super().__init__()VKeyboard(自己)tk.Entry(root).grid()tk.Button(root, text='withdraw').grid()如果 __name__ == __main__":Kiosk().mainloop()

使用 Python 测试:3.5 - 'TclVersion':8.6 'TkVersion':8.6

I'm having a problem with opening and closing the virtual keyboard made with Tkinter. I'm creating a GUI the user will browse it using touchscreen display and the user needs to input on entries.

I've tried var_name.bind('FocusIn', callback) to call the virtual keyboard and var_name.bind('FocusOut',callback) to close the virtual keyboard but when I used both the virtual keyboard is opening and then closing right away.

I hope you guys can help me here's my code:

import tkinter as tk

def select(entry, value, event):
    focused_entry.insert("end", event)
    pyautogui.press(event)
    global uppercase
    uppercase = False

    if value == "Space":
        value = ' '
    elif value == 'Enter':
        value = '\n'
    elif value == 'Tab':
        value = '\t'

    if value == "Backspace":
        if isinstance(entry, tk.Entry):
            entry.delete(len(entry.get())-1, 'end')
        #elif isinstance(entry, tk.Text):
        else: # tk.Text
            entry.delete('end - 2c', 'end')
    elif value in ('Caps Lock', 'Shift'):
        uppercase = not uppercase # change True to False, or False to True
    else:
        if uppercase:
            value = value.upper()
        entry.insert('end', value)
    return

def create(root, entry):
    alphabets = [
        ['`','1','2','3','4','5','6','7','8','9','0','-','=','Backspace'],
        ['Tab','q','w','e','r','t','y','u','i','o','p','[',']',"\\"],
        ['Caps Lock','a','s','d','f','g','h','j','k','l',';',"'",'Enter'],
        ['Shift','z','x','c','v','b','n','m',',','.','/','Shift'],
        ['Space']
    ]    

    global window
    window = tk.Toplevel(root)
    window.configure(background="cornflowerblue")
    window.geometry("+0+483")
    window.wm_attributes("-alpha", 0.7)

    for y, row in enumerate(alphabets):

        x = 0

        #for x, text in enumerate(row):
        for text in row:

            if text in ('Enter', 'Shift'):
                width = 18
                columnspan = 2
            elif text == 'Space':
                width = 124
                columnspan = 16
            elif text == 'Backspace':
                width = 10
                columnspan = 1
            elif text == '\\':
                width = 10
                columnspan = 1
            elif text == 'Tab':
                width = 10
                columnspan = 1
            elif text == '`':
                width = 10
                columnspan = 1
            elif text == 'Caps Lock':
                width = 10
                columnspan = 1
            else:                
                width = 4
                columnspan = 1

            tk.Button(window, text=text, width=width, 
                      command=lambda value=text: select(entry, value),
                      padx=3, pady=3, bd=12, bg="black", fg="white", takefocus = False
                     ).grid(row=y, column=x, columnspan=columnspan)

            x+= columnspan


# --- main ---

def remember_focus(event):
    global focused_entry
    focused_entry = event.widget

if __name__ == '__main__':
    root = tk.Tk()
    root.title('Test Keyboard')

    label = tk.Label(root, text='Test Keyboard')
    label.grid(row=0, column=0, columnspan=2)

    entry1 = tk.Entry(root)
    entry1.grid(row=1, column=0, sticky='news')
    entry1.bind("<FocusIn>", remember_focus)

    entry2 = tk.Entry(root)
    entry2.grid(row=2, column=0, sticky='news')
    entry2.bind("<FocusIn>", remember_focus)

    text1 = tk.Text(root)
    text1.grid(row=3, column=0, sticky='news')
    text1.bind("<FocusIn>", remember_focus)

    root.mainloop()

thank you sir @furas for helping me create the virtual keyboard. I edited the code and tried Bryan Oakley's answer here Tkinter check which Entry last had focus

解决方案

Question: call and close a virtual keyboard using touchscreen display

Instead of call and close, Instantiate your virtual keyboard once and use the Toplevel methodes .deiconify() and .withdraw().

Don't bind the event '<FocusIn>' to every input widget, bind to application level using bind_all(....


Reference:


Core point:

  • Use .bind_all('<FocusIn>', ... to .deiconify()
  • Use .bind_all('<Button-1>', ... to .withdraw()

# VKeyboard.py
import tkinter as tk


class VKeyboard(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)
        # Don't show the 'Toplevel' at instantiation
        super().withdraw()
                
        self.create()
        
        # Process all application == parent events
        parent.bind_all('<FocusIn>', self.on_event, add='+')
        parent.bind_all('<Button-1>', self.on_event, add='+')
    
    def on_event(self, event):
        w = event.widget
        
        # Don't process the own Button
        if w.master is not self:
            w_class_name = w.winfo_class()
            
            if w_class_name in ('Entry',):
                if self.state() == 'withdrawn':
                    self.deiconify()
                
                self.entry = w
            
            elif w_class_name in ('Button',):
                super().withdraw()
                w.focus_force()

    def create(self):
        # define the virtual keyboard `tk.Button`
        pass

Usage

import tkinter as tk
from VKeyboard import VKeyboard


class Kiosk(tk.Tk):
    def __init__(self):
        super().__init__()
        
        VKeyboard(self)

        tk.Entry(root).grid()
        tk.Button(root, text='withdraw').grid()
                 

if __name__ == "__main__":
    Kiosk().mainloop()

Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6

这篇关于如何使用触摸屏显示调用和关闭 Tkinter 制作的虚拟键盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆