2016-12-09 1 views
0

GUI를 빌드하는 작은 파이썬 프로그램이 있습니다. 텍스트 위젯을 사용하여 세로로 쌓인 프레임이 포함 된 쉽게 스크롤 가능한 창을 만들려고합니다. 프레임이 버튼 누름에서 작성되고 텍스트 위젯의 맨 아래에 추가됩니다. 이것은 잘 작동합니다. 그러나 텍스트 상자를 가로로 채우기 위해이 프레임을 늘리는 데 어려움을 겪고 있습니다.Tkinter 텍스트 위젯 가로 채우기

import Tkinter as tk 

class NewEntry(tk.Frame): 

    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 

     #self.pack(fill="x", expand=True) #possible error source 
     self.grid_columnconfigure(0, weight=1) 
     self.grid_rowconfigure(0,weight=1) 

     textField = tk.Entry(self) 
     textField.grid(row=1, column=0, padx=2, pady=1, sticky="ew") 

     addButton = tk.Button(self, text="Add", cursor="arrow") 
     addButton.grid(row=1, column=1, padx=10, pady=2, sticky="ew") 

     newLabel = tk.Label(self, text="Test", bg="#5522FF") 
     newLabel.grid(row=0, padx=2, pady=2, sticky="ew", columnspan=2) 
     newLabel.columnconfigure(0, weight=1) 

class MainApplication(tk.Frame): 

    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent) 
     self.parent=parent 

     self.grid() 
     self.columnconfigure(0, weight=1) 
     self.grid_rowconfigure(0,weight=1) 

     self.text = tk.Text(self, wrap="none", bg="#AA3333") 
     vsb = tk.Scrollbar(orient="vertical", command=self.text.yview) 
     self.text.configure(yscrollcommand=vsb.set) 
     vsb.pack(side="right", fill="y") 
     self.text.pack(fill="both", expand=True) 

     b = tk.Button(self, text="Button #%s" % 1, command=self.OnButtonClick) 
     self.text.window_create("end", window=b) 
     self.text.insert("end", "\n") 

    def OnButtonClick(self): 
     self.text.configure(state="normal") 
     panel = NewEntry(self.text, bg="#FF1111") 
     self.text.window_create("end", window=panel) 
     self.text.insert("end", "\n") 
     self.text.configure(state="disabled") 

if __name__=="__main__": 
    root = tk.Tk() 
    root.resizable(True, True) 
    appinstance=MainApplication(root) 
    appinstance.pack(fill="both", expand=True) 
    root.mainloop() 

나는 등 여러 가지 grid_columnconfigure에 대해 이야기 게시물 채우기 옵션, 끈적 옵션을 읽었습니다,하지만 난 그것을 제대로 작성 얻을 수 없었다. 텍스트 위젯의 window_create() 메서드가 크기 제한을 생성하는지 궁금합니다. NewEntry 클래스의 코드가 window_create 메서드에서 허용하는 공간을 제대로 채우는 것처럼 보이지만 텍스트 상자의 너비를 채우기 위해 "패널"을 만드는 방법을 알지 못합니다.

저는 텍스트 상자 대신 캔버스를 사용할 가능성에 대해서도 알고 있습니다.하지만 동적 크기와 스크롤 가능성을 유지하려고합니다. 당신이 간단한 위젯 스택을 가지고 있다면, 텍스트 위젯이 가장 쉽다는 여러 기사를 읽었습니다. 그래도 나는 어떤 권고도 받아 들일 것이다.

+0

이것이 실제 코드입니까? "내부에 기하학 관리자 팩을 사용할 수 없습니다."라는 오류가 나타납니다." –

+0

방금 ​​복사 한 내용을 복사하여 붙여 넣기하여 실제로 변경하지 않았는지 확인합니다. 문제가 발생하면 Python 2.7을 실행하고 있습니다. – Tarm

+0

코드에 버그가 분명히 있습니다.이 정확한 코드는 사용할 수없는 것 같습니다. –

답변

0

문제의 근본 원인은 프레임이 일반적으로 내용에 적합하기를 원한다는 것입니다. 따라서 라벨, 항목 위젯 및 버튼을 프레임에 추가하면 크기에 맞게 축소됩니다. 프레임에 지정한 크기는 무시됩니다.

이 문제에 대한 해결책은 여러 가지가 있습니다. 많은 사람들이하는 일은 기하학 전파를 없애는 것입니다 (예 : self.grid_propagate(False)).하지만 실제로는 너비를 제어해야하는 경우 너비와 높이를 모두 관리해야합니다.

또 다른 해결책은 명시적인 너비로 구성 할 수있는 패널 내부에 무언가를 넣는 것입니다. 그런 다음 포함하는 프레임이 커지도록 만듭니다. 그와

class NewEntry(tk.Frame): 
    def __init__(...): 
     ... 
     # create this _before_ creating the other widgets 
     # so it is lowest in the stacking order 
     self.sizer = tk.Frame(self, height=1) 
     self.sizer.grid(row=0, columnspan=2) 
     ... 

, 당신 : 당신이 그것을 포함하는 프레임이 성장하게됩니다이 프레임의 폭을 변경하는 경우 예를 들어, 행 0에있는 다른 위젯 뒤에 앉아 행 0에서 보이지 않는 프레임을 추가 할 수 있습니다 당신이 선별기의 폭을 설정하여 원하는 폭으로 패널을 강제 할 수 있지만, Tkinter를 위젯에 대한 최적의 높이를 계산하는 것입니다 :

self.sizer.configure(width=200) 

지금 방금 바인딩을 설정해야합니다 그래서 때마다 텍스트 위젯이 크기를 변경하면이 함수를 호출하여 각 항목의 크기를 조정합니다.

예를 들어 나중에 모든 패널을 반복 할 수 있도록 모든 패널을 목록에 저장하고자 할 수 있습니다.

class MainApplication(...): 
    def __init__(...): 
     ... 
     self.text.bind("<Configure>", self.OnConfigure) 
     ... 

    def OnConfigure(self, event): 
     for panel in self.panels: 
      panel.sizer.configure(width=event.width) 

나는 그것을 단단히 커플 때문에 정확하게 그 같은에 대한 패널의 구현을 그것을 할 것이다 : 그와

class MainApplication(...): 
    def __init__(...): 
     ... 
     self.panels = [] 
     ... 

    def OnButtonClick(...): 
     ... 
     panel = NewEntry(...) 
     self.panels.append(panel) 
     ... 

, 당신은 창 크기가 변경 될 때마다 트리거가 바인딩 설정할 수 있습니다 주 윈도우이지만, 임베디드 윈도우의 너비를 명시 적으로 제어하는 ​​일반적인 기술을 보여줍니다.

다른 솔루션은 포함하는 프레임 안에 패널을 넣고 해당 프레임을 텍스트 위젯에 추가 된 유일한 위젯으로 만듭니다. 또한 텍스트 위젯 대신 캔버스를 사용할 수도 있습니다.이 기능을 사용하면 포함 된 창의 너비와 높이를 명시 적으로 설정할 수 있기 때문입니다.

+0

"다른 솔루션은 포함하는 프레임 안에 패널을 넣는 작업과 관련이 있습니다."한 번 생각해 보았지만 Text 위젯의 스크롤 기능을 재정의한다고 가정했습니다. ems. 그렇지 않은가요? – Tarm

+0

자신의 코드가 이에 대한 답을 제공합니다. 프레임을 잘 스크롤하는 것을 볼 수 있습니다. 하나의 큰 프레임을 사용하여 잃는 것은 한 번에 한 줄씩 스크롤하는 기능입니다. 전체 프레임이 한 줄로 간주되기 때문입니다. –

+0

하지만 아무 것도 없으므로 뒤에 숨겨진 보이지 않는 프레임의 너비를 변경할 수 없습니다. 그래서 틴터는 그것을 단순히 무시할 것입니다, 논리가 어떻게 작용 하는가? @BryanOakley –