2016-11-27 6 views
0

저는 python에서 tkinter를 사용하여 json 편집기를 만들고 있습니다.캔버스에서 스크롤 막대가 작동하지 않습니다.

Canvas을 만들고 Frame을 넣어서 스크롤바를 추가했습니다.

그런 다음 Scrollbar 명령을 canvas.yview로 설정했습니다.

Theres는 엉망인 두 가지이며, 나는 그 이유를 모릅니다.

  1. 나는 (아래 화살표) 캔버스가 때마다 있기 때문에, 대신 프레임으로 지금 내가 창 (루트) 상에 스크롤 막대를 포장하고

  2. 스크롤되지 스크롤 버튼을 누를 때 나는 그것을 프레임에 포장하면 tkinter 응용 프로그램이 열리지 않고 컴퓨터 팬이 켜기 시작합니다 ... 아무도 무슨 일이 일어나고 있는지 알고 있습니까? 여기

내 코드입니다 (따라서 스크롤이 코드를 실행하려고하면 작은입니다) : 그것은 조금 긴

import Tkinter as tk 
import webbrowser 
import os 
import bjson as bj 

class App: 
    def __init__(self, master): 
     self.window = master 
     self.window.geometry("800x450") 
     self.canvas = tk.Canvas(self.window, width=800, height=400) 
     self.master = tk.Frame(self.canvas, width=800, height=400) 
     self.canvas.pack() 
     self.master.place(x=0, y=0) 
     scrollbar = tk.Scrollbar(self.window) 
     scrollbar.pack(side=tk.RIGHT, fill=tk.Y) 
     scrollbar.config(command=self.canvas.yview) 

    def init(self): 
     master = self.master 
     self.frames = { 
      "Home": HomeFrame(master) 
     } 
     self.openFrame = None 
     self.loadFrame("Home") 

    def loadFrame(self, frame): 
     self.openFrame = self.frames[frame] 
     self.openFrame.display() 

    def setTitle(self, t): 
     self.window.title(t) 

class Frame: 
    def __init__(self, master): 
     self.master = master 
     self.frame = tk.Frame(master) 
     self.frame.grid(row=0, column=0, sticky='news') 
     self.init() 
     self.frame_create() 

    def display(self): 
     self.frame.tkraise() #raises frame to top 
     self.frame_load()  #initializes the frame 

    def clear(self): 
     for widget in self.frame.winfo_children(): 
      widget.destroy() 

    def init(self): pass 
    def frame_load(self): pass 
    def frame_create(self): pass 

class HomeFrame(Frame): 
    def frame_create(self): 
     p = self.frame 
     for i in range(20): 
      tk.Label(p, text="This is content... " + str(i)).pack() 
      for j in range(2): 
       LineBreak(p) 

def LineBreak(p): 
    tk.Label(p, text="").pack() 

root = tk.Tk() 
glob = {} 
app = App(root) 
app.init() 
root.mainloop() 

단축

편집> 코드 및 좀 지저분하지만, 당신은 스크롤바를 추가하는 방법을보아야합니다. __init__App입니다.

누구나 무슨 일이 일어나는지 알 것입니다. 에, 그리고 그것을 고치는 방법?

미리 감사드립니다.

+0

가능한 한 모든 코드를 삭제하면서 나쁜 행동을 보여주는 예를 제공하십시오. [최소한의 완전하고 검증 가능한 예제를 만드는 방법] (http://www.stackoverflow.com/help/mcve) –

+0

동일한 문제가있는 코드를 단축 버전으로 업데이트했습니다. 당신의 도움을 주셔서 감사합니다. –

답변

0

코드에 많은 문제가 있습니다. 그러나 스크롤바가 제대로 작동하지 않는 문제는 무시하려는 두 가지 사항과 관련이 있습니다.

먼저 스크롤 막대와 위젯은 양방향 통신이 필요합니다. 캔버스에 스크롤바에 대해 알려야하고 스크롤바에 캔버스에 대한 정보가 있어야합니다. 당신은 다른 사람이 아닌을하고있다 :

self.canvas.configure(yscrollcommand=scrollbar.set) 
scrollbar.configure(command=self.canvas.yview) 

둘째, 당신은 캔버스의 scrollregion 속성을 구성해야합니다. 그러면 tkinter는 큰 가상 캔버스의 어떤 부분을 볼 수 있는지 알려줍니다. 일반적으로 이것은 캔버스의 <Configure> 메서드 바인딩에서 이루어지며 일반적으로 캔버스의 모든 경계 상자에 설정하려고합니다. 후자는 bbox 방법에 문자열 "all"을 전달할 수 있습니다 : 당신은 스크롤로 할 영역의 정확한 크기를 알고있는 경우

self.canvas.configure(scrollregion=self.canvas.bbox("all")) 

, 당신은 단순히 값으로 설정할 수 있습니다 (예 : scrollregion=(0,0,1000,1000)는 스크롤 1000x1000 픽셀의 영역에서).

포인트 # 2의 이유는 동일한 부모를 공유하는 위젯에 packgrid을 모두 사용할 수 없기 때문입니다. 그렇게하면 당신이 묘사하는 행동을하게됩니다. grid이 위젯을 모두 레이아웃하려고하기 때문입니다. 이로 인해 일부 위젯의 크기가 변경 될 수 있습니다. pack은 하나 이상의 위젯의 크기가 변경된 것을 확인하고 모든 위젯을 다시 레이아웃하려고합니다. 이로 인해 일부 위젯의 크기가 변경 될 수 있습니다.grid은 하나 이상의 위젯의 크기가 변경된 것을 확인하고 모든 위젯을 다시 레이아웃하려고합니다. 등등.