【问题标题】:Stretch scrollbar to canvas size in Tkinter在 Tkinter 中将滚动条拉伸到画布大小
【发布时间】:2014-03-29 14:59:18
【问题描述】:

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

我错过了什么?

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    这里发生了几件事。

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

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

    第三,您没有为行和列赋予任何权重,因此它们不会按照您预期的方式调整大小。在您的情况下,您希望为包含画布的行和列赋予 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”一个蓝色背景,给画布一个粉红色背景,等等。查看每个项目的去向以及它们如何相对于彼此调整大小变得更加容易。如果没有这个,有时可能很难知道屏幕上的一些空白区域是否属于主窗口、子窗口等。

    【讨论】:

    • 谢谢,在petem的帮助下已经解决了,但你的回答正是我所做的,所以谢谢。肯定会使用 bg 颜色提示..
    【解决方案2】:

    您的滚动条不需要框架。删除这些并将滚动条添加到 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

    【讨论】:

    • 感谢您的回复。我之前试过,但是画布会缩小以匹配滚动条,粘在西北角...
    • 我认为在画布中嵌入滚动条不是一个好主意——您在画布上绘制的任何内容都可能最终位于滚动条下方。此外,OP 混合打包和网格的方式非常好。您可以(并且应该!)将它们混合在一个应用程序中,而不是在同一个小部件中。
    • 终于搞定了!我将 self 传递给滚动条而不是 self.canvas。感谢您的指示。
    • 好电话。 Yonadav,这是一个很好的参考,你正在尝试做什么:stackoverflow.com/questions/7727804/…
    猜你喜欢
    • 2014-06-04
    • 1970-01-01
    • 2017-07-03
    • 2021-06-30
    • 1970-01-01
    • 2016-11-21
    • 2012-10-29
    • 1970-01-01
    • 2012-05-09
    相关资源
    最近更新 更多