在 Python 中使用滚动条显示大图像 [英] Show Large Image using Scrollbar in Python

查看:123
本文介绍了在 Python 中使用滚动条显示大图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

(基于这个问题:

解决方案

如果您想要一个 Scrollable 图像小部件,那么最好的方法是创建一个 Scrollable Image 类,它会排列并看起来更适合您的代码.因此,我为此创建了一个类,并添加了 bind 以便人们可以滚动鼠标以更方便地查看图像.


这是代码示例

导入 tkinter类 ScrollableImage(tkinter.Frame):def __init__(self, master=None, **kw):self.image = kw.pop('image', None)sw = kw.pop('滚动条宽度', 10)super(ScrollableImage, self).__init__(master=master, **kw)self.cnvs = tkinter.Canvas(self, highlightthickness=0, **kw)self.cnvs.create_image(0, 0, anchor='nw', image=self.image)# 垂直和水平滚动条self.v_scroll = tkinter.Scrollbar(self, orient='vertical', width=sw)self.h_scroll = tkinter.Scrollbar(self, orient='horizo​​ntal', width=sw)# 网格并配置权重.self.cnvs.grid(row=0, column=0,sticky='nsew')self.h_scroll.grid(row=1, column=0,sticky='ew')self.v_scroll.grid(row=0, column=1,sticky='ns')self.rowconfigure(0, weight=1)self.columnconfigure(0, weight=1)# 将滚动条设置为画布self.cnvs.config(xscrollcommand=self.h_scroll.set,yscrollcommand=self.v_scroll.set)# 将画布视图设置为滚动条self.v_scroll.config(command=self.cnvs.yview)self.h_scroll.config(command=self.cnvs.xview)# 指定要滚动的区域self.cnvs.config(scrollregion=self.cnvs.bbox('all'))self.cnvs.bind_class(self.cnvs, "", self.mouse_scroll)def mouse_scroll(self, evt):如果 evt.state == 0 :self.cnvs.yview_scroll(-1*(evt.delta), 'units') # MacOSself.cnvs.yview_scroll(int(-1*(evt.delta/120)), 'units') # 对于windows如果 evt.state == 1:self.cnvs.xview_scroll(-1*(evt.delta), 'units') # MacOSself.cnvs.xview_scroll(int(-1*(evt.delta/120)), 'units') # 对于windows


如何使用类?

ScrollableImage 类视为 Tkinter 的一个小部件,并像使用任何其他 Tkinter 小部件一样使用,因为如果您看到 tkinter 的源代码.

您可以通过多种方式使用 ScrollableImage.

  1. 将上述代码保存到一个新的 .py(例如:scrollimage.py") 文件中作为一个包相同的目录,然后像 from scrollimage import ScrollableImage 一样导入到你的主类中,然后将其用作普通小部件.

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

示例:

将 tkinter 导入为 tk# 如果保存在不同的 .py 文件中,则导入包否则粘贴# ScrollableImage 类在您导入后立即生效.从 scrollimage 导入 ScrollableImage根 = tk.Tk()# 来自 tkinter 的 PhotoImage 仅支持:- PGM、PPM、GIF、PNG 格式.# 要使用更多格式,请使用 PIL ImageTk.PhotoImageimg = tk.PhotoImage(file=logo.png")image_window = ScrollableImage(root, image=img, scrollbarwidth=6,宽度=200,高度=200)image_window.pack()root.mainloop()


bind 需要在 Windows 上进行一些修改,例如将 event.delta 除以 120.在 macOS 上不需要修改.在 X11 上,您需要同时绑定 并将 event.delta 除以 120.

  • Tkinter 鼠标滚轮绑定

    有关 bind 的更多详细信息以及它在不同平台上的工作原理,请查看上面的链接.

  • 构建 Tkinter 应用程序的最佳方式.

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

I would like to display an image using tkinter (Python 3). The image is very long. Therefore, I would like to add a vertical scrollbar. This is what I have tried:

(based on this question: 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()


I get the following:

I am able to plot the image, but the scrollbars are not working. They are simply grey and non-functioning.

解决方案

If you want a Scrollable image widget then the best way would be to create a class of Scrollable Image that'll arrange and look nicer to your code. So I created a class for the same and also added bind <MouseWheel> so one can scroll through their mouse to view the image more conveniently.


Here is the code sample

import tkinter

class ScrollableImage(tkinter.Frame):
    def __init__(self, master=None, **kw):
        self.image = kw.pop('image', None)
        sw = kw.pop('scrollbarwidth', 10)
        super(ScrollableImage, self).__init__(master=master, **kw)
        self.cnvs = tkinter.Canvas(self, highlightthickness=0, **kw)
        self.cnvs.create_image(0, 0, anchor='nw', image=self.image)
        # Vertical and Horizontal scrollbars
        self.v_scroll = tkinter.Scrollbar(self, orient='vertical', width=sw)
        self.h_scroll = tkinter.Scrollbar(self, orient='horizontal', width=sw)
        # Grid and configure weight.
        self.cnvs.grid(row=0, column=0,  sticky='nsew')
        self.h_scroll.grid(row=1, column=0, sticky='ew')
        self.v_scroll.grid(row=0, column=1, sticky='ns')
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        # Set the scrollbars to the canvas
        self.cnvs.config(xscrollcommand=self.h_scroll.set, 
                           yscrollcommand=self.v_scroll.set)
        # Set canvas view to the scrollbars
        self.v_scroll.config(command=self.cnvs.yview)
        self.h_scroll.config(command=self.cnvs.xview)
        # Assign the region to be scrolled 
        self.cnvs.config(scrollregion=self.cnvs.bbox('all'))
        self.cnvs.bind_class(self.cnvs, "<MouseWheel>", self.mouse_scroll)

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


How to use the class?

Treat ScrollableImage class as a widget of Tkinter and use just like you use any other Tkinter widget as every other widget is a class on their own if you see the source code of tkinter.

There are different ways through which you can use ScrollableImage.

  1. Save the above code to a new <name>.py( for ex: "scrollimage.py" ) file as a package in the same directory and then import into your main class like from scrollimage import ScrollableImage and then use it as a normal widget.

  2. Or you can keep the ScrollableImage class at the top after the imports of your main file and use it just like normal.

Example:

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")

image_window = ScrollableImage(root, image=img, scrollbarwidth=6, 
                               width=200, height=200)
image_window.pack()

root.mainloop()


The bind <MouseWheel> needs some modifications on windows like divide event.delta by 120. On macOS no modifications needed. And on X11 you need to bind both <Button-4>, <Button-5> and also divide event.delta by 120.

  • Tkinter Mousewheel Binding

    For more details on bind <MouseWheel> and how it works on different platforms can check the above link.

  • Best way to structure Tkinter application.

    You can refer to the above link to read in detail about how you can apply oops in Tkinter properly. When you use OOPs you can always inherit any widget of Tkinter and modify it to make new widgets and useful classes that'll help you to make an application with Tkinter better.

这篇关于在 Python 中使用滚动条显示大图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆