앱을 빌드하기 위해 Tkinter를 사용하고 있으며 스크롤 가능한 창이 필요합니다. Canvas : ScrollContainer를 사용하여 스크롤 가능한 컨테이너를 만들었습니다 . 그 후에는 다른 별도의 TopLevel 창을 여는 버튼을 넣는이 컨테이너에 프로그램의 주요 논리를 통합했습니다. 이 별도의 창은 스크롤 가능해야합니다. 따라서 동일한 컨테이너 클래스에도 포함합니다.
이제 문제 : 프로그램을 실행하면 메인 창이 잘 스크롤됩니다. 버튼을 클릭 한 후 TopLevel 창을 엽니 다. 보조 창이 잘 스크롤됩니다. 나는 후 닫고 메인 창을 통해 다시 차 창을 가져가 마우스를, 지금은 스크롤하지 않습니다와 나는 콘솔에서 오류가 발생합니다 :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\mirel.voicu\Anaconda3\envs\gis385\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:/Users/mirel.voicu/Desktop/python_projects/TKINTER/standalone_program/test.py", line 45, in _on_mousewheel
self.my_canvas.yview_scroll(int(-1*(event.delta/120)), "units")
File "C:\Users\mirel.voicu\Anaconda3\envs\gis385\lib\tkinter\__init__.py", line 1929, in yview_scroll
self.tk.call(self._w, 'yview', 'scroll', number, what)
_tkinter.TclError: invalid command name ".!toplevel.!frame.!canvas"
참고 : 대신 self.my_canvas.bind_all("<MouseWheel>", self._on_mousewheel)
시도해 보았지만 self.my_canvas.bind("<MouseWheel>", self._on_mousewheel)
지금은 오류가 없습니다. 그러나 스크롤링이 변경됩니다. 레이블 위로 마우스를 가져 가면 더 이상 스크롤 할 수 없습니다. 창을 확대하고 오른쪽에서 약간 마우스를 가져 가면 스크롤 할 수 있습니다. 스크롤 가능한 유일한 엔티티이기 때문에 캔버스 위로 마우스를 가져와야하기 때문이라고 생각합니다.
ScrollContainer 클래스 :
from tkinter import *
from tkinter import ttk
class ScrollContainer (ttk.Frame):
def __init__(self, container,w,h,*args, **kwargs):
super().__init__(container, *args, **kwargs)
# Create a main frame
self.main_frame = Frame(container, width=w, height=h)
self.main_frame.pack(side=TOP,fill=BOTH, expand=1) # expand frame to the size of the container
# create a canvas
self.my_canvas = Canvas(self.main_frame)
self.my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
self.my_canvas.bind_all("<MouseWheel>", self._on_mousewheel)
# add h and v scrollbar to canvas
self.my_vscrollbar = ttk.Scrollbar(self.main_frame, orient=VERTICAL, command=self.my_canvas.yview)
self.my_vscrollbar.pack(side=RIGHT, fill=Y)
self.my_hscrollbar = ttk.Scrollbar(container, orient=HORIZONTAL, command=self.my_canvas.xview)
self.my_hscrollbar.pack(side=BOTTOM, fill=X)
# configure canvas
self.my_canvas.configure(yscrollcommand=self.my_vscrollbar.set, xscrollcommand=self.my_hscrollbar.set)
self.my_canvas.bind('<Configure>', lambda e: self.my_canvas.configure(scrollregion=self.my_canvas.bbox('all')))
# create another frame inside the canvas
self.second_frame = Frame(self.my_canvas)
# add that new frame to a window in the canvas
self.my_canvas.create_window((0, 0), window=self.second_frame, anchor='nw')
def _on_mousewheel(self, event):
self.my_canvas.yview_scroll(int(-1*(event.delta/120)), "units")
주요 프로그램 로직 :
def open():
w=Toplevel()
SecondContainer=ScrollContainer(w,1000,768)
for thing in range(40):
Label(SecondContainer.second_frame, text=f"It's Friday {thing} ").grid(row=thing, column=0)
root=Tk()
MainContainer=ScrollContainer(root,1000,768)
btn=Button(MainContainer.second_frame, text="New Window",bg='yellow',command=open)
btn.grid(row=0,column=0)
for thing in range(1,30):
Label(MainContainer.second_frame,text=f"It's Friday {thing} ").grid(row=thing,column=0)
# frame design
root.mainloop()
bind_all()
응용 프로그램 바인딩 을 사용했기 때문 입니다. 따라서의 바인딩 Toplevel()
은 root
. 최상위 레벨이 파괴되면 바인딩 함수는 여전히 최상위 레벨의 캔버스를 참조하므로 예외입니다.
창 단위 바인딩을 사용해야합니다.
class ScrollContainer(ttk.Frame):
def __init__(self, container, w, h, *args, **kwargs):
super().__init__(container, *args, **kwargs)
container.bind("<MouseWheel>", self._on_mousewheel) # bind on the parent window
# Create a main frame
self.main_frame = Frame(container, width=w, height=h)
self.main_frame.pack(side=TOP, fill=BOTH, expand=1) # expand frame to the size of the container
# create a canvas
self.my_canvas = Canvas(self.main_frame)
self.my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
#self.my_canvas.bind_all("<MouseWheel>", self._on_mousewheel)
# add h and v scrollbar to canvas
self.my_vscrollbar = ttk.Scrollbar(self.main_frame, orient=VERTICAL, command=self.my_canvas.yview)
self.my_vscrollbar.pack(side=RIGHT, fill=Y)
self.my_hscrollbar = ttk.Scrollbar(container, orient=HORIZONTAL, command=self.my_canvas.xview)
self.my_hscrollbar.pack(side=BOTTOM, fill=X)
# configure canvas
self.my_canvas.configure(yscrollcommand=self.my_vscrollbar.set, xscrollcommand=self.my_hscrollbar.set)
self.my_canvas.bind('<Configure>', lambda e: self.my_canvas.configure(scrollregion=self.my_canvas.bbox('all')))
# create another frame inside the canvas
self.second_frame = Frame(self.my_canvas)
# add that new frame to a window in the canvas
self.my_canvas.create_window((0, 0), window=self.second_frame, anchor='nw')
def _on_mousewheel(self, event):
self.my_canvas.yview_scroll(int(-1*(event.delta/120)), "units")
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다