在Python中使用滚动条显示大图

时间:2019-05-08 15:07:11

标签: python tkinter

我想使用tkinter(Python 3)显示图像。图像很长。因此,我想添加一个垂直滚动条。这是我尝试过的:

(基于此问题:Scrollbars for a .jpg image on a Tkinter Canvas in Python

import tkinter
import PIL.Image, PIL.ImageTk

# Create a window
window = tkinter.Tk()

frame = tkinter.Frame(window, bd=2) # relief=SUNKEN)

frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)

xscrollbar = tkinter.Scrollbar(frame, orient=tkinter.HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=tkinter.E+tkinter.W)

yscrollbar = tkinter.Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=tkinter.N+tkinter.S)

canvas = tkinter.Canvas(frame, bd=0, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set)
canvas.grid(row=0, column=0, sticky=tkinter.N+tkinter.S+tkinter.E+tkinter.W)
canvas.config(scrollregion=canvas.bbox(tkinter.ALL))

File = "FILEPATH"
img = PIL.ImageTk.PhotoImage(PIL.Image.open(File))
canvas.create_image(0,0,image=img, anchor="nw")

xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)

frame.pack()
window.mainloop()

我得到以下信息:

我能够绘制图像,但是滚动条不起作用。它们只是灰色且无法正常工作。

enter image description here

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:3)

设置线:

canvas.config(scrollregion=canvas.bbox(tkinter.ALL))

之后:

canvas.create_image(0,0,image=img, anchor="nw")

或画布在滚动区域中不包含图像。

答案 1 :(得分:3)

在绘制图像后,设置画布的滚动区域

canvas.create_image(0, 0, image=img, anchor="nw")
canvas.config(scrollregion=canvas.bbox(tkinter.ALL))

答案 2 :(得分:3)

如果您想要可滚动图像小部件,那么最好的方法是创建一个可滚动图像类,该类将对代码进行排列并使其看起来更好。因此,我为此创建了一个类,并添加了绑定<MouseWheel>,以便人们可以滚动鼠标来更方便地查看图像。


这是代码示例

import tkinter
from PIL import ImageTk, Image

class ScrollableImage(tkinter.Canvas):
    def __init__(self, master=None, **kw):
        self.image = kw.pop('image', None)
        super(ScrollableImage, self).__init__(master=master, **kw)
        self['highlightthickness'] = 0
        self.propagate(0)  # wont let the scrollbars rule the size of Canvas
        self.create_image(0,0, anchor='nw', image=self.image)
        # Vertical and Horizontal scrollbars
        self.v_scroll = tkinter.Scrollbar(self, orient='vertical', width=6)
        self.h_scroll = tkinter.Scrollbar(self, orient='horizontal', width=6)
        self.v_scroll.pack(side='right', fill='y')
        self.h_scroll.pack(side='bottom', fill='x')
        # Set the scrollbars to the canvas
        self.config(xscrollcommand=self.h_scroll.set, 
                yscrollcommand=self.v_scroll.set)
        # Set canvas view to the scrollbars
        self.v_scroll.config(command=self.yview)
        self.h_scroll.config(command=self.xview)
        # Assign the region to be scrolled 
        self.config(scrollregion=self.bbox('all'))

        self.focus_set()
        self.bind_class(self, "<MouseWheel>", self.mouse_scroll)

    def mouse_scroll(self, evt):
        if evt.state == 0 :
            # self.yview_scroll(-1*(evt.delta), 'units') # For MacOS
            self.yview_scroll( int(-1*(evt.delta/120)) , 'units') # For windows
        if evt.state == 1:
            # self.xview_scroll(-1*(evt.delta), 'units') # For MacOS
            self.xview_scroll( int(-1*(evt.delta/120)) , 'units') # For windows

# --------- Example and testing ---------
# This will be true only if the file is not imported as a package.
if __name__ == "__main__":      
    root = tkinter.Tk()
    img = Image.open('test.jpg')
    img = ImageTk.PhotoImage(img)
    ScrollableImage(root, image=img, width=200, height=200).pack()
    root.mainloop()

如何使用课程?

ScrollableImage类作为tkinter的一个小部件,就像您使用任何其他tkinter的小部件一样使用,因为如果您看到source code of tkinter,则每个其他小部件都是一个单独的类。

使用ScrollableImage的方式有多种。

  1. 将上述代码保存为新的<name>.py (例如ex:“ scrollimage.py”)作为同一目录中的包,然后导入到您的主类中像from scrollimage import ScrollableImage,然后像普通小部件一样使用它。

  2. 或者您可以在导入主文件后将ScrollableImage类保留在顶部,并像往常一样使用它。

示例:

import tkinter as tk
# Import the package if saved in a different .py file else paste 
# the ScrollableImage class right after your imports.
from scrollimage import ScrollableImage   

root = tk.Tk()

# PhotoImage from tkinter only supports:- PGM, PPM, GIF, PNG format.
# To use more formats use PIL ImageTk.PhotoImage
img = tk.PhotoImage(file="logo.png")

show_image = ScrollableImage(root, image=img)
show_image.pack()

root.mainloop()

在窗口上,绑定<MouseWheel>需要进行一些修改,例如将event.delta除以120。在MacOS上,不需要进行任何修改。在X11上,您需要同时绑定<Button-4><Button-5>event.delta除以120。

  • Tkinter Mousewheel Binding

    有关绑定<MouseWheel>及其在不同平台上如何工作的更多详细信息,请查看上面的链接。

  • Best way to structure tkinter application.

    您可以参考上面的链接,详细了解如何在tkinter中正确应用oop。使用OOP时,您始终可以继承tkinter的任何小部件并对其进行修改,以创建新的小部件和有用的类,这些类将帮助您使tkinter的应用程序更好。