在 Tkinter 中将滚动条拉伸到画布大小 [英] Stretch scrollbar to canvas size in Tkinter

查看:24
本文介绍了在 Tkinter 中将滚动条拉伸到画布大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对 Tkinter 相当陌生.我查看了很多关于这个问题的帖子,但没有一个为我修复它.我正在尝试创建一个简单的 GUI,其中我有一个显示图像的画布.画布是可滚动的,但滚动条不会拉伸到画布的大小.

Fairly new to Tkinter. I've looked in numerous posts about this issue, but none fixed it for me. I'm trying to create a simple GUI, in which I have a canvas which displays an image. The canvas is scrollable, but the scrollbars won't stretch to the size of the canvas.

以下是我的代码的相关部分.这里没有实际显示图像的代码,图像由 openFileDialog 给出,但滚动条与图像保持一致.

Following is the relevant part of my code. there is no code here actually displaying the image, the image is given by an openFileDialog, but the scrollbars remain the same with the image.

from Tkinter import *
import Image
import ImageTk
import numpy as np
import tkFileDialog
import os as os

class DIP(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent) 
        self.parent = parent        
        self.initUI()
        self.isOpenedYet = False

    def initUI(self):
        self.parent.title("Viewer")
        self.pack(fill = BOTH, expand = 1)

        menubar = Menu(self.parent)
        self.parent.config(menu = menubar)

        vsframe = Frame(self, width=500, height=500)
        vsframe.grid(row = 1, column = 2, columnspan = 2, sticky = "nw")
        hsframe = Frame(self, width=500, height=500)
        hsframe.grid(row = 2, column = 1, rowspan = 2, sticky = "nw")
        self.canv = Canvas(self, relief=SUNKEN)
        self.canv.config(width=500, height=500)
        self.canv.config(highlightthickness=0)
        self.sbarV = Scrollbar(vsframe, orient=VERTICAL)
        self.sbarH = Scrollbar(hsframe, orient=HORIZONTAL)
        self.sbarV.config(command=self.canv.yview)
        self.sbarH.config(command=self.canv.xview)

        self.canv.config(yscrollcommand=self.sbarV.set)
        self.canv.config(xscrollcommand=self.sbarH.set)

        self.sbarV.pack(expand = YES, fill=BOTH)
        self.sbarH.pack(expand = YES, fill=BOTH)

        self.label2 = Label(self, border = 5)
        self.label2.grid(row = 0, column = 1)
        self.canv.grid(row = 1, column = 1, sticky = "nw")

        #Open Image Menu
        fileMenu = Menu(menubar)
        fileMenu.add_command(label = "Open", command = self.onOpen)
        menubar.add_cascade(label = "File", menu = fileMenu)

        #menu for algorithms
        basicMenu = Menu(menubar)
        basicMenu.add_command(label = "Super Resolution-stub", command = self.SuperRes)
        menubar.add_cascade(label = "Algorithms", menu = basicMenu)

我错过了什么?

推荐答案

这里有几件事情正在发生.

There are a couple things that are going on here.

首先,您不需要将滚动条放在单独的框架中.它们可以(并且通常应该)与画布位于同一帧中.

First, you don't need to put the scrollbars in separate frames. They can (and normally should) go in the same frame as the canvas.

其次,您的滚动框架没有正确的粘性"值.垂直滚动条需要粘"到给定区域的顶部和底部,水平滚动条需要粘"在给定区域的左侧和右侧.此外,您的画布应该粘"到其区域的所有侧面,以便填充该区域.

Second, your scroll frames don't have the right "sticky" values. A vertical scrollbar needs to "stick" to both the top and bottom of the area it is given, and a horizontal one needs to "stick" to the left and right of the area it is given. Also, your canvas should "stick" to all sides of its area so that it fills the area.

第三,您没有给行和列赋予任何权重,因此它们不会按照您预期的方式调整大小.在您的情况下,您希望为包含画布的行和列赋予 1(一)的权重,因此它占用了 GUI 中的所有额外空间.

Third, you aren't giving any weights to your rows and columns, so they don't resize the way you might expect. In your case, you want to give the row and column that contains the canvas a weight of 1 (one), so it takes up all of the extra space in the GUI.

综合考虑所有这些建议,以下是获得您想要的东西的方法:

Taking all that advice together, here's how to possibly get what you are wanting:

def initUI(self):
    self.parent.title("Viewer")
    self.pack(fill = BOTH, expand = 1)

    menubar = Menu(self.parent)
    self.parent.config(menu = menubar)

    self.grid_rowconfigure(1, weight=1)
    self.grid_columnconfigure(1, weight=1)

    self.canv = Canvas(self, relief=SUNKEN)
    self.canv.config(width=500, height=500)
    self.canv.config(highlightthickness=0)
    self.sbarV = Scrollbar(self, orient=VERTICAL)
    self.sbarH = Scrollbar(self, orient=HORIZONTAL)

    self.sbarV.config(command=self.canv.yview)
    self.sbarH.config(command=self.canv.xview)

    self.canv.config(yscrollcommand=self.sbarV.set)
    self.canv.config(xscrollcommand=self.sbarH.set)

    self.sbarV.grid(row=1, column=2, sticky="ns")
    self.sbarH.grid(row=2, column=1, sticky="ew")

    self.label2 = Label(self, border = 5, text="label 2")
    self.label2.grid(row = 0, column = 1)
    self.canv.grid(row = 1, column = 1, sticky = "nsew")

    ...

顺便说一下,这里有一个调试问题的技巧:在开发过程中给每个大"小部件(框架、画布、文本小部件)一个独特的背景颜色.例如,给self"一个蓝色背景,给画布一个粉红色背景,等等.查看每个项目的去向以及它们如何相对于彼此调整大小变得更加容易.没有这个,有时很难知道屏幕上的一些空白区域是否属于主窗口、子窗口等.

By the way, here's a tip for debugging problems like this: give each "large" widget (frames, canvases, text widgets) a distinctive background color during development. For example, give "self" a background of blue, the canvas a background of pink, and so on. It becomes much easier to see where each item is going and how they resize relative to each other. Without this, it can sometimes be hard to know if some white space on the screen belongs to the main window, a child window, etc.

这篇关于在 Tkinter 中将滚动条拉伸到画布大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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