【发布时间】:2020-07-20 04:21:39
【问题描述】:
我正在做一个小项目,并制作了一个小屏幕键盘作为 tkinter Toplevel
我的应用程序是这样构建的:
- 根窗口(Tk 小部件)
- 输入 1(入口小部件)
- 输入 2(入口小部件)
- 输入 3(文本小部件)
- on_screen-keyboard (Toplevel-Widget)
Toplevel-Widget 包含按钮,以及应在条目中输入文本的回调(就像键盘按钮一样)
我想要的是键盘/键盘的子级与最后一个活动输入小部件之间的通信。我的问题是,我不知道如何说键盘,它应该向哪个输入小部件发送消息。
import tkinter as tk
from tkinter import ttk
class MainWindow(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.active_input = tk.Variable(value=None)
ttk.Button(self, text="show Keyboard", command=lambda: Keyboard(self)).pack()
self.text = tk.StringVar(value="")
self.input1 = ttk.Entry(self)
self.input1.bind("<FocusIn>", lambda e: self.active_input.set(self.input1))
self.input2 = ttk.Entry(self)
self.input2.bind("<FocusIn>", lambda e: self.active_input.set(self.input2))
self.input3 = tk.Text(self, height=3, width=15)
self.input3.bind("<FocusIn>", lambda e: self.active_input.set(self.input3))
self.input1.pack()
self.input3.pack()
self.input2.pack()
class Keyboard(tk.Toplevel):
OPENED = False
NAME = "- Keyboard -"
NUM = [{"text":"1", "width":1},
{"text":"2", "width":1},
{"text":"3", "width":2}]
CHAR= [{"text":"A", "width":1},
{"text":"B", "width":1},
{"text":"C", "width":2}]
def __init__(self, master):
if not Keyboard.OPENED:
Keyboard.OPENED = True
print("keyboard opened!")
self.master = master
tk.Toplevel.__init__(self, master)
self.title(self.NAME)
self.protocol("WM_DELETE_WINDOW", self.close)
self.keyb_nb = ttk.Notebook(self)
self.keyb_nb.pack()
self.num_tab = ttk.Frame(self.keyb_nb)
self.createPad(self.num_tab, Keyboard.NUM,2)
self.keyb_nb.add(self.num_tab, text="123")
self.char_tab = ttk.Frame(self.keyb_nb)
self.createPad(self.char_tab, Keyboard.CHAR, 2)
self.keyb_nb.add(self.char_tab, text="ABC")
def createPad(self, master, pad:list, max_col):
self.co_count = 0
self.ro = 1
for button in pad:
button["id"] = ttk.Button(master, width=6*button["width"], text=button["text"], command=self.bclicked(button))
if self.co_count >= max_col:
self.ro = self.ro + 1
self.co_count = 0
button["id"].grid(row=self.ro, columnspan=button["width"], column=self.co_count)
self.co_count = self.co_count+button["width"]
def bclicked(self, button:dict):
"""
reciver = self.master.active_input #I think the Problem here is, that the variable contains a string, not a widget
reciever.focus_force()
reciever.insert(index=tk.INSERT, string=button["text"])
"""
pass
def close(self):
Keyboard.OPENED = False
self.destroy()
print("keyboard closed!")
root = MainWindow()
root.mainloop()
这里 Mainwindow 的 init 和 Keyboard 类的 bclicked 很重要...
代码已准备好调试
我希望有一个解决方案,类似于互联网中的通信(发送者=按钮、接收者 ID、消息),但非常欢迎每个可行的解决方案
顺便说一句:我也在寻找一个解决方案,我如何不必强制输入聚焦并且顶层保持在屏幕的最高层(如果我聚焦 Tk-Widget/其中一个输入/按钮,键盘将留在它的前面)
摘要:当键盘顶层已经获得焦点时,我如何找出 3 个输入小部件中的哪一个最后处于活动状态?
【问题讨论】:
-
你应该在
.bind(...)中使用lambda。 -
对不起,但这不能回答我的问题
-
是的,通常我使用 lambda,我只是在编写这个示例时忘记了它,因为我的代码比上面的更复杂
标签: python tkinter communication