user3486991
user3486991

Reputation: 463

tkinter trapping frame entrance (followup)

This question a followup to Trapping Frame Entrance in tkinter in which @jasonharper provided a very helpful answer.

In the code that follows, I bind entrance to the canvas (self.c) in order to toggle switching some fields from display mode to edit mode. That seems to work fine for the textarea but not for the menuarea: I can click on the button to display the menuarea button, but when the mouse moves to the actual menu, the "Leave" event on the canvas is triggered, and so I cannot make a choice from the menu. The solution provided for the original post does not seem to apply here?

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()

Upvotes: 1

Views: 46

Answers (1)

Josselin
Josselin

Reputation: 2643

I guess you are monitoring the <Leave> event of your self.c canvas because you plan to have multiple frames/canvases in your final app.

In that case, you could achieve the effect you want by binding your widget re-arranging function to the <Enter> events of each of these frames/canvases:

# 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))

Upvotes: 1

Related Questions