2017-09-16 10 views
0

캔버스에 레이블을 하나씩 배열하고 싶습니다. 그러나 배치는 원하는대로 나오지 않습니다.Tkinter : Canvas를 상대적으로 Canvas에 배치합니다.

다음은 캔버스에 레이블을 삽입하는 기능입니다. 그러나 for 루프에있는 것들은 중첩됩니다. 이유 - 일부 레이블의 크기가 다른 레이블보다 큽니다. 따라서 가장 큰 크기는 80이고 게재 위치는 각각 가정합니다. 이 접근법을 바꾸고 싶습니다. 오히려 나는 라벨을 상대적으로 하나씩 배치하기를 원합니다.

def calculate(*args): 
try: 
    ttk.Label(canvas, text="Result:").place(x=20, y=20) 
    ttk.Label(canvas, text="Topic:").place(x=20, y=80) 
    ttk.Label(canvas, textvariable=topic).place(x=200, y=80) 
    ttk.Label(canvas, text="Environment:").place(x=20, y=120) 
    ttk.Label(canvas, textvariable=environment).place(x=200, y=120) 
    ttk.Label(canvas, text="Event Results:").place(x=20, y=160) 

    inputValue=TextArea.get("1.0","end-1c") 

    len_max=0 
    result={} 
    for s in inputValue.splitlines(): 
     data = MainInstance.searchWithPayload(s)    
     result[s]=data 
     if len(s+data) > len_max: 
      len_max = len(s+data) 

    i = 190 
    for key in result.keys(): 
     print(key) 
     print(result[key]) 
     ttk.Label(canvas, text=key+"\n\n"+result[key], wraplength=800).place(x=20,y = i) 
     i = i + 80 

except ValueError: 
    pass 

아래는 캔버스 위젯을 통합 한 코드입니다. 그리고 calculate 단추는 calculate 함수를 호출합니다.

  1. 이 어떻게 상대적으로 중복을 중지 라벨을 배치 할 수 있습니다 :

    ttk.Button(page2, text="Exit",command=page1.quit).grid(column=2, row=8) 
    ttk.Button(page2, text="Calculate", command=calculate).grid(column=3, row=8) 
    
    canvas = Canvas(root, width=900, height=universal_height) 
    canvas.grid(column=1, row=0) 
    
    
    root.mainloop() 
    

    사실, 질문의 두 부분이 있습니까?

  2. 캔버스에 스크롤을 추가하려고했습니다. 그러나 응용 프로그램이 응답하지 않고 팝업되지 않습니다. 스크롤바를 추가

코드 :

canvas=Canvas(root,bg='#FFFFFF',width=300,height=300,scrollregion= 
(0,0,500,500)) 
hbar=Scrollbar(root,orient=HORIZONTAL) 
hbar.pack(side=BOTTOM,fill=X) 
hbar.config(command=canvas.xview) 
vbar=Scrollbar(root,orient=VERTICAL) 
vbar.pack(side=RIGHT,fill=Y) 
vbar.config(command=canvas.yview) 
canvas.config(width=300,height=300) 
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set) 
canvas.pack(side=LEFT,expand=True,fill=BOTH) 

이 첫 번째 두 개의 레이블이 겹쳐지고있어서, 나는 점점 오전 출력입니다. output - overlapped labels

+0

이유 : 당신이 문제를 중복이 그것을 스크롤 할 수 create_window를 사용하여 캔버스 내부 프레임을 넣어하지 않도록

나는, 당신이 프레임을 만드는 데 내부의 모든 당신이 레이블을 그리드를 제안 '장소 '를 사용하고 있습니까? 'pack' (그리고 더 적은 정도는'grid')은 위젯을 행이나 열에 쉽게 나타 내기 위해 만들어졌습니다. –

+0

그리드를 사용하면 캔버스 창의 크기가 내용의 크기로 줄어 듭니다. 프레임 크기를 고정하려면 장소 사용을 고려했습니다. – raizsh

+0

'.grid()'가 당신에게 훨씬 좋을 것 같습니다. 모든 콘텐츠를 '캔버스'에 넣을 필요가 있습니까? –

답변

0

캔버스 안에 넣은 위젯을 스크롤하려면 label.place(...) 대신 canvas.create_window(x, y, window=label)을 사용해야합니다.

import tkinter as tk 
from tkinter import ttk 


def on_resize(event): 
    """Resize canvas scrollregion when the canvas is resized.""" 
    canvas.configure(scrollregion=canvas.bbox('all')) 

root = tk.Tk() 
root.geometry('100x100') 

root.columnconfigure(0, weight=1) 
root.rowconfigure(0, weight=1) 

canvas = tk.Canvas(root) 

frame = ttk.Frame(canvas) 
# create and grid the labels 
for i in range(3): 
    for j in range(3): 
     ttk.Label(frame, text="Label %i-%i" % (i, j)).grid(row=i, column=j, padx=10, pady=10) 
# put the frame in the canvas 
canvas.create_window(0, 0, anchor='nw', window=frame) 
# add the scrollbars 
vbar = ttk.Scrollbar(root, orient='vertical', command=canvas.yview) 
hbar = ttk.Scrollbar(root, orient='horizontal', command=canvas.xview) 
canvas.configure(xscrollcommand=hbar.set, 
       yscrollcommand=vbar.set, 
       scrollregion=canvas.bbox('all')) 

canvas.grid(row=0, column=0, sticky='eswn') 
vbar.grid(row=0, column=1, sticky='ns') 
hbar.grid(row=1, column=0, sticky='ew') 

canvas.bind('<Configure>', on_resize) 

root.mainloop()