Python tkinter陷阱框架入口(后续)

Python tkinter陷阱框架入口(后续),python,tkinter,Python,Tkinter,这个问题是对@jasonharper提供了一个非常有用答案的后续问题 在下面的代码中,我将入口绑定到画布(self.c),以便将一些字段从显示模式切换到编辑模式。这似乎对textarea很好,但对menuarea却不行:我可以点击按钮来显示menuarea按钮,但当鼠标移动到实际菜单时,画布上的“离开”事件被触发,因此我无法从菜单中进行选择。为原始职位提供的解决方案似乎不适用于这里 from tkinter import * from tkinter import ttk class MainW

这个问题是对@jasonharper提供了一个非常有用答案的后续问题

在下面的代码中,我将入口绑定到画布(self.c),以便将一些字段从显示模式切换到编辑模式。这似乎对textarea很好,但对menuarea却不行:我可以点击按钮来显示menuarea按钮,但当鼠标移动到实际菜单时,画布上的“离开”事件被触发,因此我无法从菜单中进行选择。为原始职位提供的解决方案似乎不适用于这里

from tkinter import *
from tkinter import ttk
class MainWindow(Frame):
    def __init__(self,master):
        super().__init__(master)
        self.master = master
        self.pack()
        self.edit = 0
        self.initUI()

    def initUI(self):
        self.c = Canvas(self, height = 100, width = 400,bg = "white")
        self.c.pack()
        self.c.bind('<Enter>', lambda *args: self.trigger(1))
        self.c.bind('<Leave>', lambda *args: self.trigger(0))
        self.textstring = StringVar()
        self.textstring.set("Day")
        self.textarea = TextArea(self.c,self.edit,self.textstring)
        self.textarea.display(2)
        self.menuarea = MenuArea(self.c,self.edit,self.textstring)
        self.menuarea.display(2)
        self.c.create_window(10,10,window = self.textarea,anchor = NW)
        self.c.create_window(200,10, window = self.menuarea, anchor = NW)
    def trigger(self,x):
        if x == 0:
            self.textarea.display(0)
            self.menuarea.display(0)
        elif x == 1:
            self.textarea.display(1)
            self.menuarea.display(1)
class TextArea(Frame):
    def __init__(self,master,active,textstr):
        super().__init__(master)
        self.master = master
        self.active = active
        self.textstr = textstr
        self.optionslist = ["GS","NR","JY"]
    def display(self,e):
        if e == 0:
            for child in self.winfo_children():
                child.destroy()
            L = Label(self,text = self.textstr.get())
            L.pack()
        elif e ==1:
            for child in self.winfo_children():
                child.destroy()
            E = Entry(self,textvariable = self.textstr)
            E.pack(anchor = S)
        elif e == 2:
            L = Label(self, text=self.textstr.get(), relief="flat")
            L.pack()

class MenuArea(Frame):
    def __init__(self,master,active,textstr):
        super().__init__(master)
        self.master = master
        self.textstr = textstr
        self.optionslist = ["GS", "NR", "JY"]
    def display(self,e):
        if e == 0:
            for child in self.winfo_children():
                child.destroy()
            L = Label(self,text = self.textstr.get())
            L.pack()
        elif e ==1:
            for child in self.winfo_children():
                child.destroy()
            E = OptionMenu(self,self.textstr,"Tu", "Wed")
            E.config(relief = "flat", width = 3)
            E.pack()
        elif e == 2:
            L = Label(self, text=self.textstr.get())
            L.pack()

root = Tk()
mainframe = MainWindow(root)
mainframe.pack()
root.mainloop()
从tkinter导入*
从tkinter导入ttk
类主窗口(框架):
定义初始(自我,主):
超级()。\uuuu初始化\uuuuu(主)
self.master=master
self.pack()
self.edit=0
self.initUI()
def initUI(self):
self.c=画布(self,高度=100,宽度=400,bg=“白色”)
self.c.pack()
self.c.bind(“”,lambda*args:self.trigger(1))
self.c.bind(“”,lambda*args:self.trigger(0))
self.textstring=StringVar()
self.textstring.set(“日”)
self.textarea=textarea(self.c、self.edit、self.textstring)
self.textarea.display(2)
self.menuarea=menuarea(self.c、self.edit、self.textstring)
自我菜单区域显示(2)
self.c.create_窗口(10,10,窗口=self.textarea,锚点=NW)
self.c.create_window(200,10,window=self.menuarea,anchor=NW)
def触发器(自身,x):
如果x==0:
self.textarea.display(0)
self.menuarea.display(0)
elif x==1:
self.textarea.display(1)
自菜单区域显示(1)
类文本区域(框架):
定义初始化(自、主、活动、文本):
超级()。\uuuu初始化\uuuuu(主)
self.master=master
self.active=active
self.textstr=textstr
self.optionslist=[“GS”、“NR”、“JY”]
def显示(自我,e):
如果e==0:
用于自个儿。winfo_children():
child.destroy()
L=标签(self,text=self.textstr.get())
L.pack()
elif e==1:
用于自个儿。winfo_children():
child.destroy()
E=条目(self,textvariable=self.textstr)
E.pack(锚定=S)
elif e==2:
L=标签(self,text=self.textstr.get(),relief=“flat”)
L.pack()
类菜单(框架):
定义初始化(自、主、活动、文本):
超级()。\uuuu初始化\uuuuu(主)
self.master=master
self.textstr=textstr
self.optionslist=[“GS”、“NR”、“JY”]
def显示(自我,e):
如果e==0:
用于自个儿。winfo_children():
child.destroy()
L=标签(self,text=self.textstr.get())
L.pack()
elif e==1:
用于自个儿。winfo_children():
child.destroy()
E=选项菜单(self,self.textstr,“Tu”,“Wed”)
E.config(relief=“flat”,宽度=3)
E.包装()
elif e==2:
L=标签(self,text=self.textstr.get())
L.pack()
root=Tk()
大型机=主窗口(根)
mainframe.pack()
root.mainloop()

我猜您正在监视您的
self.c
画布的
事件,因为您计划在最终应用程序中有多个帧/画布

在这种情况下,您可以通过将小部件重新排列功能绑定到每个帧/画布的
事件来实现想要的效果:

# High-level parts of the GUI
self.c = Canvas(self, height=100, width=400, bg="white")
self.c.pack()
self.c2 = Canvas(self, height=100, width=400, bg="yellow")
self.c2.pack()

# Re-arrange the widgets when entering different parts of the GUI
self.c.bind('<Enter>', lambda *args: self.trigger(1))
self.c2.bind('<Enter>', lambda *args: self.trigger(0))
#GUI的高级部分
self.c=画布(self,高度=100,宽度=400,bg=“白色”)
self.c.pack()
self.c2=画布(self,高度=100,宽度=400,bg=“黄色”)
self.c2.pack()
#当进入GUI的不同部分时,重新排列小部件
self.c.bind(“”,lambda*args:self.trigger(1))
self.c2.bind(“”,lambda*args:self.trigger(0))

我也曾有过这种可能性,可能不得不求助于此。将鼠标移到一个弹出菜单上,这是一个帧的子菜单,这在我看来是一个错误。