在Tkinter中将滚动条拉伸到画布大小

时间:2014-02-26 16:22:41

标签: python tkinter

Tkinter相当新鲜。 我已经看了很多关于这个问题的帖子,但没有一个针对我。 我正在尝试创建一个简单的GUI,其中我有一个显示图像的画布。 画布是可滚动的,但滚动条不会拉伸到画布的大小。

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

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)

我错过了什么?

2 个答案:

答案 0 :(得分:2)

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

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

其次,您的滚动框架没有正确的“粘滞”值。垂直滚动条需要“粘住”它所给区域的顶部和底部,而水平滚动条需要“粘住”它所给区域的左侧和右侧。此外,您的画布应“粘住”其区域的所有边,以便填充该区域。

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

将所有建议放在一起,以下是如何获得您想要的东西:

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”一个蓝色的背景,画布为粉红色的背景,依此类推。变得更容易看到每个项目的去向以及它们如何相对于彼此调整大小。如果没有这个,有时很难知道屏幕上的某些空白是否属于主窗口,子窗口等。

答案 1 :(得分:0)

滚动条不需要框架。删除它们并将滚动条添加到Canvas小部件:

self.sbarV = Scrollbar(self.canv, orient=VERTICAL)
self.sbarH = Scrollbar(self.canv, orient=HORIZONTAL)

然后,使用.grid()作为滚动条。混合包和网格不是一个好主意。使用网格中的粘性选项将滚动条粘贴到Canvas

的范围内
self.sbarV.grid(column=1, sticky=N+S)
self.sbarH.grid(row=1, sticky=E+W)

这样做应该解决它,其他一切看起来都正确。

更多:http://effbot.org/zone/tkinter-scrollbar-patterns.htm