2017-05-12 1 views
1

이 질문에 대한 대답은 Trapping Frame Entrance in tkinter입니다. @jasonharper는 매우 유용한 답변을 제공했습니다.tkinter 트래핑 프레임 입구 (followup)

다음 코드에서 일부 필드를 표시 모드에서 편집 모드로 전환하는 것을 토글하기 위해 캔버스 입구 (self.c)를 바인드합니다. 그 textarea에 대한 있지만 메뉴 영역에 대한 작동하지 않는 것 : 메뉴 영역 단추를 표시하려면 단추를 클릭 할 수 있지만 마우스를 실제 메뉴로 이동하면 "캔버스에"이벤트가 트리거됩니다 및 그래서 나 메뉴에서 선택할 수 없습니다. 원래 게시물에 제공된 솔루션이 여기에 적용되지 않는 것 같습니다.

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

답변

1

나는 당신이 당신의 최종 응용 프로그램에서 여러 프레임/캔버스를 계획하기 때문에 당신이 당신의 self.c 캔버스의 <Leave> 이벤트를 모니터링하는 것 같아요. 이 경우

, 이러한 프레임/캔버스 각각의 <Enter> 이벤트에 위젯 재 배열 기능을 결합하여 원하는 효과를 얻을 수있다 : 너무 나에게 일어난 가능성의

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

, 그것에 의지해야 할지도 모른다. 프레임을 떠날 때 프레임의 자식 인 팝업 메뉴 위로 마우스를 움직이는 것이 내게 실수 인 것처럼 보입니다. – user3486991