2012-06-22 2 views
3

버튼이 포함 된 상위 위젯이 있습니다. 버튼을 누르면 왼쪽면에 정렬 된 부모 위젯 바로 아래에 경계선없는 (즉, Windows 장식 단추가 없음) 창을 열고 싶습니다. 나는 창 위치를 설정하는 유일한 방법은 .geometry()을 사용하고 있지만 부모 위젯의 절대 좌표를 얻을 수없는 것 같아서 당황 스럽다. 나는 .geometry()의 오프셋 만 필요하다. 부모의 부모. 지금까지 내 코드는 다음과 같습니다.Tkinter 파이썬에서 부모를 기준으로 자식 창 배치하기

# This is the child which appears when the button is pressed. 
class ChildPopUpWindow(Frame): 
    def __init__(self, parentWgdt): 
     win = Toplevel(parentWgdt) 
     geom = str(parentWgdt.winfo_x()) + '+' + str(parentWgdt.winfo_y() + parentWgdt.winfo_height()) 
     win.overrideredirect(1) # No win decoration. 
     win.bd = 10 
     win.relief = GROOVE 
     win.geometry(geom) 
     Frame.__init__(self, win) 
     # etc. etc. 

    # ... and this is the handler for the button being pressed. 
    def onDropDown(self): 
     popUp = ChildPopUpWindow(self) 

위와 같이하면 창은 부모 위젯이 아닌 데스크탑에 비례하여 표시됩니다. 그것은 또한 내가 볼 수있는 한 국경의 두께와 구제를 고려하지 않는 것처럼 보인다. 누구든지이 일을 할 수있는 방법을 제공 할 수 있습니까? .geometry() 갈 길이 멀거나 더 좋은 방법이 있습니까?

+0

팝업 창을 만들고 클래스 이름에 PopUpWindow가 표시되지만 Toplevel이 아닌 Frame을 상속한다고 말합니다. 그 이유가 있을까요? 나는 이것을 어떻게 사용하는지 잘 모른다. ChildPopUpWindow 프레임 안에 팝업 창을 표시하는 버튼입니까? –

+0

죄송합니다. 매우 명확하지 않습니다.'onDropDown'은 버튼이있는 프레임의 핸들러입니다. 버튼을 클릭하면 버튼이있는 프레임 바로 아래에 프레임이없는 (즉, Windows 최대화/최소화/닫기 버튼 없음) 팝업이 표시됩니다. 이것은 모달 방식으로 본질적으로 작동 할 것입니다. 단, 팝업에서 선택하거나 단추를 다시 누르면 닫을 수 있습니다. 이런 식으로 캘린더 나 색상 선택기 드롭 다운과 같은 효과가 있습니다. –

+0

@BryanOakley : Toplevel/Frame 혼란은이 작업을 수행하기 위해 여러 가지 시도를하고 있기 때문에 발생합니다. 필자가 찾은 대부분의 예제는 Toplevel 윈도우를 생성 한 다음이를 Frame-inhereting 클래스의 매개 변수로 전달하는 것처럼 보입니다. 나는 이것을 따라 가기를 원했고 프레임 이전에 Toplevel 윈도우의 매개 변수를 설정하려고 시도했다. 그러나 생성자를 'ChildPopUpWindow' 클래스에 캡슐화하고 싶었다. 의견을 말하고 올바르게 수정하십시오. –

답변

4

간단히 대답하면 winfo_rootxwinfo_rooty을 사용하면 화면에 상대적인 좌표를 얻을 수 있습니다. 그리고 예, wm_geometry은 최상위 창을 정확하게 배치하는 방법입니다. 예를 들어

: 친절한 조언의 조금으로

x = parentWgdt.winfo_rootx() 
    y = parentWgdt.winfo_rooty() 
    height = parentWgdt.winfo_height() 
    geom = "+%d+%d" % (x,y+height) 

, 나는 약칭의 var에 NMS에 좋습니다. 특히 약어가 잘못되었을 때 (Wgdt는 적어도 Wdgt 여야 함) 코드를 읽기 어렵게 만듭니다. geomgeometryWgdtWidget 사이의 코드 크기 차이는 작지만 가독성의 차이는 매우 큽니다.

+0

확인해 주셔서 감사합니다. 그게 본질적으로 내가 가진 것 같아요. 작동하지 않는 다른 이유가있을 것 같네요. 약어에 동의 : 게시하기 전에 서두르는 코드 (클라이언트 IP)를 난독 처리했습니다. –

0

Tk의 설명서에 따르면 "https://www.tcl.tk/man/tcl8.4/TkCmd/winfo.htm#M52" 당신이 위젯을 만든 후 바로 진정한 폭을 필요로하는 경우, 대신 윈도우의 요청 폭을 얻기 위해 그것을 준비, 또는 reqwidth winfo 사용하는 형상 관리자를 강제로 갱신를 호출의 실제 폭.

# This code works perfectly 
self.update() 

self.geometry("+%d+%d" % (self.parent.winfo_rootx()+50, 
          self.parent.winfo_rooty()+50 
         ) 
      ) 
관련 문제