在 tkinter 中捕获框架入口
Trapping Frame Entrance in tkinter
我想绑定到 entrance/exit to/from 一个框架。这很简单,但似乎当我将鼠标悬停在框架中的某个小部件上时,它被困为框架的出口(我想是因为框架不在小部件区域中 "visible"。你可以通过运行下面的代码看到这个效果,它的意思是显示一个文本字段(Label),然后在进入Frame时变成一个可编辑的字段。一旦按钮在文本区域本身,它就回到一个标签。我很难想出解决这个问题的方法。(我需要捕获框架的入口,而不仅仅是文本区域。这只是一个玩具示例)
from tkinter import *
class MainWindow(Frame):
def __init__(self,master):
super().__init__(master)
self.master = master
#self.master.state('zoomed')
self.pack()
self.edit = 0
self.initUI()
def initUI(self):
self.c = Canvas(self, height = 100, width = 400, bg = "red")
self.c.pack()
self.bind('<Enter>', lambda *args: textarea.display(1))
self.bind('<Leave>', lambda *args: textarea.display(0))
self.textstring = StringVar()
self.textstring.set("Hello")
textarea = TextArea(self.c,self.edit,self.textstring)
textarea.display(2)
self.c.create_window(10,10,window = textarea,anchor = NW)
class TextArea(Frame):
def __init__(self,master,active,textstr):
super().__init__()
self.master = master
self.active = active
self.textstr = textstr
self.inflag = False
def display(self,e):
if e == 0:
for child in self.winfo_children():
child.destroy()
L = Label(self,text = self.textstr.get(),relief = "flat")
L.pack()
elif e ==1:
for child in self.winfo_children():
child.destroy()
E = Entry(self,textvariable = self.textstr,width = 10)
E.pack()
elif e == 2:
L = Label(self, text=self.textstr.get(), relief="flat")
L.pack()
root = Tk()
mainframe = MainWindow(root)
mainframe.pack()
root.mainloop()
这里的实际问题相当微妙:在TextArea
的__init__
中,您未能将master
参数传递给超类,因此它默认为子类根 window。换句话说,TextArea 实际上是 MainWindow 的兄弟,而不是您想要的后代。因此,有必要从一个 <Leave>
到另一个 <Enter>
。解决方案是 super().__init__(master)
,就像您在 MainWindow
.
中所做的那样
我想绑定到 entrance/exit to/from 一个框架。这很简单,但似乎当我将鼠标悬停在框架中的某个小部件上时,它被困为框架的出口(我想是因为框架不在小部件区域中 "visible"。你可以通过运行下面的代码看到这个效果,它的意思是显示一个文本字段(Label),然后在进入Frame时变成一个可编辑的字段。一旦按钮在文本区域本身,它就回到一个标签。我很难想出解决这个问题的方法。(我需要捕获框架的入口,而不仅仅是文本区域。这只是一个玩具示例)
from tkinter import *
class MainWindow(Frame):
def __init__(self,master):
super().__init__(master)
self.master = master
#self.master.state('zoomed')
self.pack()
self.edit = 0
self.initUI()
def initUI(self):
self.c = Canvas(self, height = 100, width = 400, bg = "red")
self.c.pack()
self.bind('<Enter>', lambda *args: textarea.display(1))
self.bind('<Leave>', lambda *args: textarea.display(0))
self.textstring = StringVar()
self.textstring.set("Hello")
textarea = TextArea(self.c,self.edit,self.textstring)
textarea.display(2)
self.c.create_window(10,10,window = textarea,anchor = NW)
class TextArea(Frame):
def __init__(self,master,active,textstr):
super().__init__()
self.master = master
self.active = active
self.textstr = textstr
self.inflag = False
def display(self,e):
if e == 0:
for child in self.winfo_children():
child.destroy()
L = Label(self,text = self.textstr.get(),relief = "flat")
L.pack()
elif e ==1:
for child in self.winfo_children():
child.destroy()
E = Entry(self,textvariable = self.textstr,width = 10)
E.pack()
elif e == 2:
L = Label(self, text=self.textstr.get(), relief="flat")
L.pack()
root = Tk()
mainframe = MainWindow(root)
mainframe.pack()
root.mainloop()
这里的实际问题相当微妙:在TextArea
的__init__
中,您未能将master
参数传递给超类,因此它默认为子类根 window。换句话说,TextArea 实际上是 MainWindow 的兄弟,而不是您想要的后代。因此,有必要从一个 <Leave>
到另一个 <Enter>
。解决方案是 super().__init__(master)
,就像您在 MainWindow
.