[PYTHON] 여러 개의 Tkinter 목록 상자를 함께 스크롤하기
PYTHON여러 개의 Tkinter 목록 상자를 함께 스크롤하기
하나의 스크롤바를 사용하여 여러 개의 Tkinter 목록 상자를 스크롤 할 수 있지만 목록 상자에서 마우스 휠 활동을 함께 스크롤 할 수 있습니다.
이 작업을 수행하는 방법?
현재 코드는 여기에 설명 된 마지막 패턴을 기반으로합니다 : http://effbot.org/tkinterbook/listbox.htm 스크롤바 만 사용하면 잘 작동하지만 마우스 휠을 사용하면 목록 상자가 독립적으로 스크롤됩니다.
해결법
-
==============================
1.두 개의 위젯을 단일 스크롤 막대에 연결 한 것과 같은 방식으로 문제를 해결하십시오. 마우스 휠에 대한 사용자 정의 바인딩을 생성하고 이러한 바인딩이 단지 하나가 아닌 두 개의 목록 상자 모두에 영향을 주도록하십시오.
두 개의 위젯을 단일 스크롤 막대에 연결 한 것과 같은 방식으로 문제를 해결하십시오. 마우스 휠에 대한 사용자 정의 바인딩을 생성하고 이러한 바인딩이 단지 하나가 아닌 두 개의 목록 상자 모두에 영향을 주도록하십시오.
유일한 실제 트릭은 플랫폼에 따라 마우스 휠에 대한 다른 이벤트를 얻는 것입니다. Windows 및 Mac은
이벤트를 가져오고, Linux는 및 이벤트를 가져옵니다. 필자의 Mac에서 python 2.5로 테스트 한 예가 있습니다.
import Tkinter as tk class App: def __init__(self): self.root=tk.Tk() self.vsb = tk.Scrollbar(orient="vertical", command=self.OnVsb) self.lb1 = tk.Listbox(self.root, yscrollcommand=self.vsb.set) self.lb2 = tk.Listbox(self.root, yscrollcommand=self.vsb.set) self.vsb.pack(side="right",fill="y") self.lb1.pack(side="left",fill="x", expand=True) self.lb2.pack(side="left",fill="x", expand=True) self.lb1.bind("<MouseWheel>", self.OnMouseWheel) self.lb2.bind("<MouseWheel>", self.OnMouseWheel) for i in range(100): self.lb1.insert("end","item %s" % i) self.lb2.insert("end","item %s" % i) self.root.mainloop() def OnVsb(self, *args): self.lb1.yview(*args) self.lb2.yview(*args) def OnMouseWheel(self, event): self.lb1.yview("scroll", event.delta,"units") self.lb2.yview("scroll",event.delta,"units") # this prevents default bindings from firing, which # would end up scrolling the widget twice return "break" app=App()
-
==============================
2.나는 이것이 꽤 오래되었다는 것을 알고 있지만, 해결책은 여기에있는 것들보다 조금 더 간단하다고 생각합니다. 목록 상자를 항상 일치시키기를 원한다면 위의 두 가지 대답은 완전한 해결책이 아닙니다. 화살표 키로 선택을 변경하면 하나의 목록 상자가 스크롤되지만 다른 목록 상자는 스크롤되지 않습니다.
나는 이것이 꽤 오래되었다는 것을 알고 있지만, 해결책은 여기에있는 것들보다 조금 더 간단하다고 생각합니다. 목록 상자를 항상 일치시키기를 원한다면 위의 두 가지 대답은 완전한 해결책이 아닙니다. 화살표 키로 선택을 변경하면 하나의 목록 상자가 스크롤되지만 다른 목록 상자는 스크롤되지 않습니다.
그래서 응답을 살펴보면서 나는 스크롤바에 곧바로 보내는 대신 yscrollcommand 콜백을 연결하지 않는 이유를 묻습니다. 그래서, 나는 단지 그것을했다 :
try: from Tkinter import * except ImportError: from tkinter import * class MultipleScrollingListbox(Tk): def __init__(self): Tk.__init__(self) self.title('Scrolling Multiple Listboxes') #the shared scrollbar self.scrollbar = Scrollbar(self, orient='vertical') #note that yscrollcommand is set to a custom method for each listbox self.list1 = Listbox(self, yscrollcommand=self.yscroll1) self.list1.pack(fill='y', side='left') self.list2 = Listbox(self, yscrollcommand=self.yscroll2) self.list2.pack(expand=1, fill='both', side='left') self.scrollbar.config(command=self.yview) self.scrollbar.pack(side='right', fill='y') #fill the listboxes with stuff for x in xrange(30): self.list1.insert('end', x) self.list2.insert('end', x) #I'm sure there's probably a slightly cleaner way to do it than this #Nevertheless - whenever one listbox updates its vertical position, #the method checks to make sure that the other one gets updated as well. #Without the check, I *think* it might recurse infinitely. #Never tested, though. def yscroll1(self, *args): if self.list2.yview() != self.list1.yview(): self.list2.yview_moveto(args[0]) self.scrollbar.set(*args) def yscroll2(self, *args): if self.list1.yview() != self.list2.yview(): self.list1.yview_moveto(args[0]) self.scrollbar.set(*args) def yview(self, *args): self.list1.yview(*args) self.list2.yview(*args) if __name__ == "__main__": root = MultipleScrollingListbox() root.mainloop()
-
==============================
3.여기에 현재 솔루션이 있습니다. 독립형 함수로 코딩되었습니다 (예, 객체 여야합니다).
여기에 현재 솔루션이 있습니다. 독립형 함수로 코딩되었습니다 (예, 객체 여야합니다).
특징 / 요구 사항 :
암호:
def showLists(l, *lists): """ Present passed equal-length lists in adjacent scrollboxes. """ # This exists mainly for me to start learning about Tkinter. # This widget reqires at least one list be passed, and as many additional # lists as desired. Each list is displayed in its own listbox, with # additional listboxes added to the right as needed to display all lists. # The width of each listbox is set to match the max width of its contents. # Caveat: Too wide or too many lists, and the widget can be wider than the screen! # The listboxes scroll together, using either the scrollbar or mousewheel. # :TODO: Refactor as an object with methods. # :TODO: Move to a separate file when other widgets are built. # Check arguments if (l is None) or (len(l) < 1): return listOfLists = [l] # Form a list of lists for subsequent processing listBoxes = [] # List of listboxes if len(lists) > 0: for list in lists: # All lists must match length of first list # :TODO: Add tail filling for short lists, with error for long lists if len(list) != len(l): return listOfLists.append(list) import Tkinter def onVsb(*args): """ When the scrollbar moves, scroll the listboxes. """ for lb in listBoxes: lb.yview(*args) def onMouseWheel(event): """ Convert mousewheel motion to scrollbar motion. """ if (event.num == 4): # Linux encodes wheel as 'buttons' 4 and 5 delta = -1 elif (event.num == 5): delta = 1 else: # Windows & OSX delta = event.delta for lb in listBoxes: lb.yview("scroll", delta, "units") # Return 'break' to prevent the default bindings from # firing, which would end up scrolling the widget twice. return "break" # Create root window and scrollbar root = Tkinter.Tk() root.title('Samples w/ time step < 0') vsb = Tkinter.Scrollbar(root, orient=Tkinter.VERTICAL, command=onVsb) vsb.pack(side=Tkinter.RIGHT, fill=Tkinter.Y) # Create listboxes for i in xrange(0,len(listOfLists)): lb = Tkinter.Listbox(root, yscrollcommand=vsb.set) lb.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH) # Bind wheel events on both Windows/OSX & Linux; lb.bind("<MouseWheel>", onMouseWheel) lb.bind("<Button-4>", onMouseWheel) lb.bind("<Button-5>", onMouseWheel) # Fill the listbox maxWidth = 0 for item in listOfLists[i]: s = str(item) if len(s) > maxWidth: maxWidth = len(s) lb.insert(Tkinter.END, s) lb.config(width=maxWidth+1) listBoxes.append(lb) # Add listbox to list of listboxes # Show the widget Tkinter.mainloop() # End of showLists()
개선을위한 제안은 환영합니다!
from https://stackoverflow.com/questions/4066974/scrolling-multiple-tkinter-listboxes-together by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Visual Studio Python 프로젝트에 CNTK virtualenv 추가 (0) | 2018.11.28 |
---|---|
[PYTHON] pandas to_csv : csv에 팬더를 쓸 때 CSV 파일의 과학 표기법을 사용하지 않습니다. (0) | 2018.11.28 |
[PYTHON] 파이 게임에서 모니터 해상도를 얻는 방법? (0) | 2018.11.28 |
[PYTHON] 이미지를 바이트 배열로 변환하는 Python 스크립트 (0) | 2018.11.28 |
[PYTHON] 헬로쿠에서 Python 셀렌으로 ChromeDriver 실행하기 (0) | 2018.11.28 |