问题描述
限时送ChatGPT账号..我在打开和关闭使用 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
创建绑定以在应用程序级别处理事件.
bind_all(sequence=None, func=无,添加=无)
向应用程序级别添加事件绑定.
核心点:
使用.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:
Events and Bindings - Section: Instance and Class Bindings
Use
bind_all
to create a binding to handle the event at application level.
bind_all(sequence=None, func=None, add=None)
Adds an event binding to the application level.
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屋!
更多推荐
[db:关键词]
发布评论