用于多个输入框的弹出式数字键盘(数字小键盘)
Popup Numpad (Numeric Keypad) for Multiple Entry Boxes
大家好。我目前正在尝试实现一个带有输入框的弹出式数字键盘,以便在 pi 4 触摸屏上使用。搜索了一段时间后,我发现 this 论坛提供了 scotty101 提供的有效解决方案。不幸的是,该代码仅对单个条目小部件有效。在用我深奥的面向对象知识摆弄了一段时间之后,我似乎无法找到一种方法来实现此代码以使用多个条目小部件。
我的代码的简化工作版本:
import tkinter as tk
from tkinter import simpledialog
from time import strftime
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page1_Widgets()
def Create_Page1_Widgets(self):
self.BackCan=tk.Canvas(self,width=800,height=440,borderwidth=0,bg="white")
self.BackCan.place(x=0,y=0)
#Entry Boxes#
self.Page1Var1 = tk.StringVar()
self.Page1Var2 = tk.StringVar()
self.Page1e1=tk.Entry(self,width=12,justify="center",textvariable=self.Page1Var1)
self.Page1e1.bind('<FocusIn>',self.numpadEntry); self.edited = False
self.Page1e1.place(x=10,y=163,width=102,height=26)
self.Page1e2=tk.Entry(self,width=12,justify="center",textvariable=self.Page1Var2)
self.Page1e2.bind('<FocusIn>',self.numpadEntry);
self.Page1e2.place(x=129,y=163,width=102,height=26)
def numpadEntry(self, event):
if self.edited == False:
self.edited = True
new = numPad(self,self)
else:
self.edited = False
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page2_Widgets()
def Create_Page2_Widgets(self):
#Validation#
#Page Backround#
self.BackCan=tk.Canvas(self,width=800,height=440,borderwidth=0,bg="white")
self.BackCan.place(x=0,y=0)
##Entry Boxes##
self.Page2Var1 = tk.StringVar()
self.Page2Var2 = tk.StringVar()
self.PrefertHRe=tk.Entry(self,width=12,justify="center",textvariable=self.Page2Var1)
self.PrefertHRe.bind('<FocusIn>',self.numpadEntry); self.edited = False #<-calls numpad
self.PrefertHRe.place(x=10,y=200,width=102,height=26)
self.PrefertMINe=tk.Entry(self,width=12,justify="center",textvariable=self.Page2Var2)
self.PrefertMINe.place(x=129,y=200,width=102,height=26)
def numpadEntry(self, event):
if self.edited == False:
self.edited = True
new = numPad(self,self)
else:
self.edited = False
class numPad(simpledialog.Dialog):
def __init__(self,master=None,parent=None):
self.parent = parent
self.top = tk.Toplevel(master=master)
self.top.protocol("WM_DELETE_WINDOW",self.ok)
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
r = 1
c = 0
n = 0
btn = []
for label in btn_list:
cmd = lambda x = label: self.click(x)
cur = tk.Button(self.top, text=label, width=6, height=3, command=cmd)
btn.append(cur)
btn[-1].grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def click(self,label):
print(label)
if label == 'Del':
currentText = self.parent.Page1Var1.get() #<--Page1Var1 need to be dynamic?
self.parent.Page1Var1.set(currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.parent.Page1Var1.get()
self.parent.Page1Var1.set(currentText+label)
def ok(self):
self.top.destroy()
self.top.master.focus()
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
super().__init__()
#Navigation Frame#
p2 = Page2(self);p1 = Page1(self)
Navigation_frame = tk.Frame(self, width=800, height=55, background="bisque")
container = tk.Frame(self)
Navigation_frame.pack(side="bottom");Navigation_frame.pack_propagate(0)
container.pack(side="top", fill="both", expand=True)
NavCan=tk.Canvas(Navigation_frame,width=800,height=55,borderwidth=0,bg="white")
NavCan.place(x=0,y=0)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(Navigation_frame, height=2, width=10, text="1", command=p1.lift)
b2 = tk.Button(Navigation_frame, height=2, width=10, text="2", command=p2.lift)
b1.place(x=144, y=6);b2.place(x=253, y=6)
#Clock#
def clock():
string = strftime('%H:%M:%S')
lbl.config(text = string); lbl.after(1000, clock)
#Clock Label#
lbl = tk.Label(Navigation_frame,font=("Arial",20,'bold'),background= 'grey',foreground
= 'black'); lbl.place(x=20, y=12)
p1.show()
clock()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("800x440")
root.attributes('-fullscreen', False)
root.mainloop()
所以问题是,有没有办法将小键盘焦点更改为另一个输入小部件的焦点?
想法是在 MainView
中有一个 current_entry
属性,其中包含当前选定的条目。然后你定义 numpadEntry()
函数作为 MainView
的方法来更新 current_entry
:
的值
def numpadEntry(self, event):
# change current entry
self.current_entry = event.widget
if self.numpad is None: # numpad does not exists
self.numpad = NumPad(self)
else:
self.numpad.lift() # make numpad visible
在这个函数中,我还假设 MainView
有一个 numpad
属性,即 NumPad window.
现在您可以将所有条目的 <FocusIn>
绑定到 numpadEntry
以编辑当前条目。然后在小键盘里,不用修改一个StringVar,而是直接用entry.delete(-1)
和entry.insert('end', <char>)
修改条目内容。
完整代码:
import tkinter as tk
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.create_widgets()
def create_widgets(self):
pass
def show(self):
self.lift()
class Page1(Page):
def create_widgets(self):
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
#Entry Boxes#
self.Page1e1 = tk.Entry(self, width=12, justify="center")
self.Page1e1.bind('<FocusIn>', self.master.numpadEntry)
self.edited = False
self.Page1e1.place(x=10, y=163, width=102, height=26)
self.Page1e2 = tk.Entry(self, width=12, justify="center")
self.Page1e2.bind('<FocusIn>', self.master.numpadEntry)
self.Page1e2.place(x=129, y=163, width=102, height=26)
class Page2(Page):
def create_widgets(self):
#Validation#
#Page Backround#
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
##Entry Boxes##
self.PrefertHRe = tk.Entry(self, width=12, justify="center")
self.PrefertHRe.bind('<FocusIn>', self.master.numpadEntry)
self.edited = False #<-calls numpad
self.PrefertHRe.place(x=10, y=200, width=102, height=26)
self.PrefertMINe = tk.Entry(self, width=12, justify="center")
self.PrefertMINe.place(x=129, y=200, width=102, height=26)
self.PrefertMINe.bind('<FocusIn>', self.master.numpadEntry)
class NumPad(tk.Toplevel):
def __init__(self, master=None):
tk.Toplevel.__init__(self, master)
self.protocol("WM_DELETE_WINDOW", self.ok)
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
r = 1
c = 0
n = 0
for label in btn_list:
cur = tk.Button(self, text=label, width=6, height=3,
command=lambda x=label: self.click(x))
cur.grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def click(self, label):
if label == 'Del':
self.master.current_entry.delete(-1)
elif label == 'Close':
self.ok()
else:
self.master.current_entry.insert('end', label)
def ok(self):
self.destroy()
self.master.focus()
self.master.numpad = None
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.numpad = None # NumPad
self.current_entry = None # currently selected entry
p2 = Page2(self)
p1 = Page1(self)
Navigation_frame = tk.Frame(self, width=800, height=55, background="bisque")
container = tk.Frame(self)
Navigation_frame.pack(side="bottom")
Navigation_frame.pack_propagate(0)
container.pack(side="top", fill="both", expand=True)
NavCan = tk.Canvas(Navigation_frame, width=800, height=55, borderwidth=0, bg="white")
NavCan.place(x=0, y=0)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(Navigation_frame, height=2, width=10, text="1", command=p1.show)
b2 = tk.Button(Navigation_frame, height=2, width=10, text="2", command=p2.show)
b1.place(x=144, y=6)
b2.place(x=253, y=6)
p1.show()
def numpadEntry(self, event):
# change current entry
self.current_entry = event.widget
# create numpad if does not exist yet
if self.numpad is None:
self.numpad = NumPad(self)
else:
self.numpad.lift()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("800x440")
root.attributes('-fullscreen', False)
root.mainloop()
我更改了事件以将 stringVar 对象传递给数字键盘。数字键盘出现一些问题,但这与您的编辑标志有关。
import tkinter as tk
from tkinter import simpledialog
from time import strftime
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page1_Widgets()
def Create_Page1_Widgets(self):
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
# Entry Boxes#
self.Page1Var1 = tk.StringVar()
self.Page1Var2 = tk.StringVar()
self.Page1e1 = tk.Entry(self, width=12, justify="center", textvariable=self.Page1Var1)
self.Page1e1.bind('<FocusIn>', lambda event: self.numpadEntry(event, self.Page1Var1))
self.edited = False
self.Page1e1.place(x=10, y=163, width=102, height=26)
self.Page1e2 = tk.Entry(self, width=12, justify="center", textvariable=self.Page1Var2)
self.Page1e2.bind('<FocusIn>', lambda event: self.numpadEntry(event, self.Page1Var2))
self.Page1e2.place(x=129, y=163, width=102, height=26)
def numpadEntry(self, event, string_var):
if self.edited == False:
self.edited = True
new = numPad(string_var)
else:
self.edited = False
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page2_Widgets()
def Create_Page2_Widgets(self):
# Validation#
# Page Backround#
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
##Entry Boxes##
self.Page2Var1 = tk.StringVar()
self.Page2Var2 = tk.StringVar()
self.PrefertHRe = tk.Entry(self, width=12, justify="center", textvariable=self.Page2Var1)
self.PrefertHRe.bind('<FocusIn>', lambda event: self.numpadEntry(event, self.Page2Var1))
self.edited = False # <-calls numpad
self.PrefertHRe.place(x=10, y=200, width=102, height=26)
self.PrefertMINe = tk.Entry(self, width=12, justify="center", textvariable=self.Page2Var2)
self.PrefertMINe.place(x=129, y=200, width=102, height=26)
def numpadEntry(self, event, string_var):
if self.edited == False:
self.edited = True
new = numPad(string_var)
else:
self.edited = False
class numPad(simpledialog.Dialog):
def __init__(self, the_entry):
self.top = tk.Toplevel(master=None)
self.top.protocol("WM_DELETE_WINDOW", self.ok)
self.the_entry_widget = the_entry
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
r = 1
c = 0
n = 0
btn = []
for label in btn_list:
cmd = lambda x=label: self.click(x)
cur = tk.Button(self.top, text=label, width=6, height=3, command=cmd)
btn.append(cur)
btn[-1].grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def click(self, label):
print(label)
if label == 'Del':
currentText = self.the_entry_widget.get() # <--Page1Var1 need to be dynamic?
self.the_entry_widget.set(currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.the_entry_widget.get()
self.the_entry_widget.set(currentText + label)
def ok(self):
self.top.destroy()
self.top.master.focus()
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
super().__init__()
# Navigation Frame#
p2 = Page2(self)
p1 = Page1(self)
Navigation_frame = tk.Frame(self, width=800, height=55, background="bisque")
container = tk.Frame(self)
Navigation_frame.pack(side="bottom")
Navigation_frame.pack_propagate(0)
container.pack(side="top", fill="both", expand=True)
NavCan = tk.Canvas(Navigation_frame, width=800, height=55, borderwidth=0, bg="white")
NavCan.place(x=0, y=0)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(Navigation_frame, height=2, width=10, text="1", command=p1.lift)
b2 = tk.Button(Navigation_frame, height=2, width=10, text="2", command=p2.lift)
b1.place(x=144, y=6)
b2.place(x=253, y=6)
# Clock#
def clock():
string = strftime('%H:%M:%S')
lbl.config(text=string)
lbl.after(1000, clock)
# Clock Label#
lbl = tk.Label(Navigation_frame, font=("Arial", 20, 'bold'), background='grey', foreground
='black')
lbl.place(x=20, y=12)
p1.show()
clock()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("800x440")
root.attributes('-fullscreen', False)
root.mainloop()
大家好。我目前正在尝试实现一个带有输入框的弹出式数字键盘,以便在 pi 4 触摸屏上使用。搜索了一段时间后,我发现 this 论坛提供了 scotty101 提供的有效解决方案。不幸的是,该代码仅对单个条目小部件有效。在用我深奥的面向对象知识摆弄了一段时间之后,我似乎无法找到一种方法来实现此代码以使用多个条目小部件。
我的代码的简化工作版本:
import tkinter as tk
from tkinter import simpledialog
from time import strftime
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page1_Widgets()
def Create_Page1_Widgets(self):
self.BackCan=tk.Canvas(self,width=800,height=440,borderwidth=0,bg="white")
self.BackCan.place(x=0,y=0)
#Entry Boxes#
self.Page1Var1 = tk.StringVar()
self.Page1Var2 = tk.StringVar()
self.Page1e1=tk.Entry(self,width=12,justify="center",textvariable=self.Page1Var1)
self.Page1e1.bind('<FocusIn>',self.numpadEntry); self.edited = False
self.Page1e1.place(x=10,y=163,width=102,height=26)
self.Page1e2=tk.Entry(self,width=12,justify="center",textvariable=self.Page1Var2)
self.Page1e2.bind('<FocusIn>',self.numpadEntry);
self.Page1e2.place(x=129,y=163,width=102,height=26)
def numpadEntry(self, event):
if self.edited == False:
self.edited = True
new = numPad(self,self)
else:
self.edited = False
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page2_Widgets()
def Create_Page2_Widgets(self):
#Validation#
#Page Backround#
self.BackCan=tk.Canvas(self,width=800,height=440,borderwidth=0,bg="white")
self.BackCan.place(x=0,y=0)
##Entry Boxes##
self.Page2Var1 = tk.StringVar()
self.Page2Var2 = tk.StringVar()
self.PrefertHRe=tk.Entry(self,width=12,justify="center",textvariable=self.Page2Var1)
self.PrefertHRe.bind('<FocusIn>',self.numpadEntry); self.edited = False #<-calls numpad
self.PrefertHRe.place(x=10,y=200,width=102,height=26)
self.PrefertMINe=tk.Entry(self,width=12,justify="center",textvariable=self.Page2Var2)
self.PrefertMINe.place(x=129,y=200,width=102,height=26)
def numpadEntry(self, event):
if self.edited == False:
self.edited = True
new = numPad(self,self)
else:
self.edited = False
class numPad(simpledialog.Dialog):
def __init__(self,master=None,parent=None):
self.parent = parent
self.top = tk.Toplevel(master=master)
self.top.protocol("WM_DELETE_WINDOW",self.ok)
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
r = 1
c = 0
n = 0
btn = []
for label in btn_list:
cmd = lambda x = label: self.click(x)
cur = tk.Button(self.top, text=label, width=6, height=3, command=cmd)
btn.append(cur)
btn[-1].grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def click(self,label):
print(label)
if label == 'Del':
currentText = self.parent.Page1Var1.get() #<--Page1Var1 need to be dynamic?
self.parent.Page1Var1.set(currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.parent.Page1Var1.get()
self.parent.Page1Var1.set(currentText+label)
def ok(self):
self.top.destroy()
self.top.master.focus()
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
super().__init__()
#Navigation Frame#
p2 = Page2(self);p1 = Page1(self)
Navigation_frame = tk.Frame(self, width=800, height=55, background="bisque")
container = tk.Frame(self)
Navigation_frame.pack(side="bottom");Navigation_frame.pack_propagate(0)
container.pack(side="top", fill="both", expand=True)
NavCan=tk.Canvas(Navigation_frame,width=800,height=55,borderwidth=0,bg="white")
NavCan.place(x=0,y=0)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(Navigation_frame, height=2, width=10, text="1", command=p1.lift)
b2 = tk.Button(Navigation_frame, height=2, width=10, text="2", command=p2.lift)
b1.place(x=144, y=6);b2.place(x=253, y=6)
#Clock#
def clock():
string = strftime('%H:%M:%S')
lbl.config(text = string); lbl.after(1000, clock)
#Clock Label#
lbl = tk.Label(Navigation_frame,font=("Arial",20,'bold'),background= 'grey',foreground
= 'black'); lbl.place(x=20, y=12)
p1.show()
clock()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("800x440")
root.attributes('-fullscreen', False)
root.mainloop()
所以问题是,有没有办法将小键盘焦点更改为另一个输入小部件的焦点?
想法是在 MainView
中有一个 current_entry
属性,其中包含当前选定的条目。然后你定义 numpadEntry()
函数作为 MainView
的方法来更新 current_entry
:
def numpadEntry(self, event):
# change current entry
self.current_entry = event.widget
if self.numpad is None: # numpad does not exists
self.numpad = NumPad(self)
else:
self.numpad.lift() # make numpad visible
在这个函数中,我还假设 MainView
有一个 numpad
属性,即 NumPad window.
现在您可以将所有条目的 <FocusIn>
绑定到 numpadEntry
以编辑当前条目。然后在小键盘里,不用修改一个StringVar,而是直接用entry.delete(-1)
和entry.insert('end', <char>)
修改条目内容。
完整代码:
import tkinter as tk
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.create_widgets()
def create_widgets(self):
pass
def show(self):
self.lift()
class Page1(Page):
def create_widgets(self):
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
#Entry Boxes#
self.Page1e1 = tk.Entry(self, width=12, justify="center")
self.Page1e1.bind('<FocusIn>', self.master.numpadEntry)
self.edited = False
self.Page1e1.place(x=10, y=163, width=102, height=26)
self.Page1e2 = tk.Entry(self, width=12, justify="center")
self.Page1e2.bind('<FocusIn>', self.master.numpadEntry)
self.Page1e2.place(x=129, y=163, width=102, height=26)
class Page2(Page):
def create_widgets(self):
#Validation#
#Page Backround#
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
##Entry Boxes##
self.PrefertHRe = tk.Entry(self, width=12, justify="center")
self.PrefertHRe.bind('<FocusIn>', self.master.numpadEntry)
self.edited = False #<-calls numpad
self.PrefertHRe.place(x=10, y=200, width=102, height=26)
self.PrefertMINe = tk.Entry(self, width=12, justify="center")
self.PrefertMINe.place(x=129, y=200, width=102, height=26)
self.PrefertMINe.bind('<FocusIn>', self.master.numpadEntry)
class NumPad(tk.Toplevel):
def __init__(self, master=None):
tk.Toplevel.__init__(self, master)
self.protocol("WM_DELETE_WINDOW", self.ok)
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
r = 1
c = 0
n = 0
for label in btn_list:
cur = tk.Button(self, text=label, width=6, height=3,
command=lambda x=label: self.click(x))
cur.grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def click(self, label):
if label == 'Del':
self.master.current_entry.delete(-1)
elif label == 'Close':
self.ok()
else:
self.master.current_entry.insert('end', label)
def ok(self):
self.destroy()
self.master.focus()
self.master.numpad = None
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.numpad = None # NumPad
self.current_entry = None # currently selected entry
p2 = Page2(self)
p1 = Page1(self)
Navigation_frame = tk.Frame(self, width=800, height=55, background="bisque")
container = tk.Frame(self)
Navigation_frame.pack(side="bottom")
Navigation_frame.pack_propagate(0)
container.pack(side="top", fill="both", expand=True)
NavCan = tk.Canvas(Navigation_frame, width=800, height=55, borderwidth=0, bg="white")
NavCan.place(x=0, y=0)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(Navigation_frame, height=2, width=10, text="1", command=p1.show)
b2 = tk.Button(Navigation_frame, height=2, width=10, text="2", command=p2.show)
b1.place(x=144, y=6)
b2.place(x=253, y=6)
p1.show()
def numpadEntry(self, event):
# change current entry
self.current_entry = event.widget
# create numpad if does not exist yet
if self.numpad is None:
self.numpad = NumPad(self)
else:
self.numpad.lift()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("800x440")
root.attributes('-fullscreen', False)
root.mainloop()
我更改了事件以将 stringVar 对象传递给数字键盘。数字键盘出现一些问题,但这与您的编辑标志有关。
import tkinter as tk
from tkinter import simpledialog
from time import strftime
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page1_Widgets()
def Create_Page1_Widgets(self):
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
# Entry Boxes#
self.Page1Var1 = tk.StringVar()
self.Page1Var2 = tk.StringVar()
self.Page1e1 = tk.Entry(self, width=12, justify="center", textvariable=self.Page1Var1)
self.Page1e1.bind('<FocusIn>', lambda event: self.numpadEntry(event, self.Page1Var1))
self.edited = False
self.Page1e1.place(x=10, y=163, width=102, height=26)
self.Page1e2 = tk.Entry(self, width=12, justify="center", textvariable=self.Page1Var2)
self.Page1e2.bind('<FocusIn>', lambda event: self.numpadEntry(event, self.Page1Var2))
self.Page1e2.place(x=129, y=163, width=102, height=26)
def numpadEntry(self, event, string_var):
if self.edited == False:
self.edited = True
new = numPad(string_var)
else:
self.edited = False
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
self.Create_Page2_Widgets()
def Create_Page2_Widgets(self):
# Validation#
# Page Backround#
self.BackCan = tk.Canvas(self, width=800, height=440, borderwidth=0, bg="white")
self.BackCan.place(x=0, y=0)
##Entry Boxes##
self.Page2Var1 = tk.StringVar()
self.Page2Var2 = tk.StringVar()
self.PrefertHRe = tk.Entry(self, width=12, justify="center", textvariable=self.Page2Var1)
self.PrefertHRe.bind('<FocusIn>', lambda event: self.numpadEntry(event, self.Page2Var1))
self.edited = False # <-calls numpad
self.PrefertHRe.place(x=10, y=200, width=102, height=26)
self.PrefertMINe = tk.Entry(self, width=12, justify="center", textvariable=self.Page2Var2)
self.PrefertMINe.place(x=129, y=200, width=102, height=26)
def numpadEntry(self, event, string_var):
if self.edited == False:
self.edited = True
new = numPad(string_var)
else:
self.edited = False
class numPad(simpledialog.Dialog):
def __init__(self, the_entry):
self.top = tk.Toplevel(master=None)
self.top.protocol("WM_DELETE_WINDOW", self.ok)
self.the_entry_widget = the_entry
self.createWidgets()
def createWidgets(self):
btn_list = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', 'Close', 'Del']
r = 1
c = 0
n = 0
btn = []
for label in btn_list:
cmd = lambda x=label: self.click(x)
cur = tk.Button(self.top, text=label, width=6, height=3, command=cmd)
btn.append(cur)
btn[-1].grid(row=r, column=c)
n += 1
c += 1
if c == 3:
c = 0
r += 1
def click(self, label):
print(label)
if label == 'Del':
currentText = self.the_entry_widget.get() # <--Page1Var1 need to be dynamic?
self.the_entry_widget.set(currentText[:-1])
elif label == 'Close':
self.ok()
else:
currentText = self.the_entry_widget.get()
self.the_entry_widget.set(currentText + label)
def ok(self):
self.top.destroy()
self.top.master.focus()
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
super().__init__()
# Navigation Frame#
p2 = Page2(self)
p1 = Page1(self)
Navigation_frame = tk.Frame(self, width=800, height=55, background="bisque")
container = tk.Frame(self)
Navigation_frame.pack(side="bottom")
Navigation_frame.pack_propagate(0)
container.pack(side="top", fill="both", expand=True)
NavCan = tk.Canvas(Navigation_frame, width=800, height=55, borderwidth=0, bg="white")
NavCan.place(x=0, y=0)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(Navigation_frame, height=2, width=10, text="1", command=p1.lift)
b2 = tk.Button(Navigation_frame, height=2, width=10, text="2", command=p2.lift)
b1.place(x=144, y=6)
b2.place(x=253, y=6)
# Clock#
def clock():
string = strftime('%H:%M:%S')
lbl.config(text=string)
lbl.after(1000, clock)
# Clock Label#
lbl = tk.Label(Navigation_frame, font=("Arial", 20, 'bold'), background='grey', foreground
='black')
lbl.place(x=20, y=12)
p1.show()
clock()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("800x440")
root.attributes('-fullscreen', False)
root.mainloop()