Ожидаемое поведение:
Я хочу иметь возможность прокручивать холст с помощью колесика мыши.
Проблема:
Прокрутка колесиком мыши перестает работать, когда мое изображение вставлено в виджет ttk.Label
(см. Метод 2 из self.loadImage()
), который находится в ttk.Frame
, который находится в виджете tk.Canvas.create_window()
. Однако прокрутка с помощью колесика мыши работает, когда мое изображение вставляется на холст методом tk.Canvas.create_image()
(см. Метод 1 из self.loadImage()
). Проблема с Python 3.6.5 и Tk.TkVersion 8.6 в Linux.
Вопрос: Почему метод 2 не работает? Как заставить это работать?
Я написал следующий тестовый скрипт, чтобы проиллюстрировать мою проблему:
import tkinter as tk
import tkinter.ttk as ttk
import platform
from PIL import Image, ImageTk
class App(ttk.Frame):
def __init__( self, parent, *args, **kwargs ):
super().__init__( parent, style='App.TFrame', borderwidth=10,
relief='raised', width=390, height=390 )
self.style = None
self.vscrollbar = None
self.canvas = None
self.canvas_window = None
self.interior = None
self.setStyle()
self.createWidgets()
self.loadImage()
self.createBinding()
self.rowconfigure( 0, weight=1 )
self.columnconfigure( 0, weight=1 )
def setStyle(self):
self.style = ttk.Style()
self.style.configure( 'App.TFrame', background='pink' )
self.style.configure( 'interior.TFrame', background='red' )
def createWidgets(self):
self.vscrollbar = ttk.Scrollbar(self, orient='vertical')
self.vscrollbar.pack( side='right', fill='y', expand='false' )
self.canvas = tk.Canvas( self,
bd=0, #no border
highlightthickness=0, #no focus highlight
yscrollcommand=self.vscrollbar.set,#use self.vscrollbar
background='blue', #improves resizing appearance
)
self.canvas.pack( side='left', fill='both', expand='true' )
self.vscrollbar.config( command=self.canvas.yview )
self.canvas.xview_moveto( 0 )
self.canvas.yview_moveto( 0 )
self.interior = ttk.Frame( self.canvas,
style='interior.TFrame',
borderwidth=10,
relief=tk.SUNKEN )
self.canvas_window = self.canvas.create_window(
0, 0, window=self.interior, anchor='nw' )
def loadImage(self):
image = './test_image.png'
image = Image.open(image)
self.image = ImageTk.PhotoImage(image)
width, height = image.size
print(width, height)
self.canvas.config( scrollregion=(0, 0, width, height) )
#Method 1
#self.canvas_obj_id = self.canvas.create_image( 0, 0, image=self.image,
# anchor=tk.NW )
#Method 2
self.label = ttk.Label(self.interior, image=self.image )
self.label.grid(row=0, column=0, sticky='nsew')
def createBinding(self):
if platform.system() == 'Linux':
self.canvas.bind('<Button-4>', self._on_mousewheel_linux)
self.canvas.bind('<Button-5>', self._on_mousewheel_linux)
print('Binded <Button-4> and <Button-5>')
elif platform.system() == 'Windows':
self.canvas.bind('<MouseWheel>', self._on_mousewheel_windows)
def _on_mousewheel_linux(self, event):
if event.num == 4: self.canvas.yview_scroll( -1, "units" )
if event.num == 5: self.canvas.yview_scroll( 1, "units" )
def _on_mousewheel_windows(self, event):
self.canvas.yview_scroll( int(-1*(event.delta/120)), "units" )
if __name__ == '__main__':
root = tk.Tk()
app = App( root )
app.grid( row=0, column=0, sticky='nsew' )
root.rowconfigure( 0, weight=1 )
root.columnconfigure( 0, weight=1 )
root.mainloop()