2014-02-26 75 views
2

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

以下是我的代码的相关部分。这里没有实际显示图像的代码,图像由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

但是也有一些这里发生了几件事情。

首先,您不需要将滚动条放在单独的框架中。他们可以(通常应该)像画布一样进入相同的框架。

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

第三,你没有对你的行和列给予任何权重,所以它们不会调整你期望的方式。在你的情况下,你想让包含画布的行和列的权重为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") 

    ... 

顺便说一句,这里有像这样的调试问题提示:给每一个“大”窗口小部件(帧,画布,文本小部件)在开发过程中具有独特的背景色。例如,给“自我”一个蓝色背景,画布背景为粉红色,等等。查看每个项目的去向以及它们相对于彼此的大小调整变得更加容易。如果没有这个,有时候很难知道屏幕上的某些空白是否属于主窗口,子窗口等。

+0

谢谢,它已经与petem的帮助,但你的答案正是我所做的,谢谢。绝对要使用bg颜色提示.. – Ysch

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

+0

感谢您的回复。 我之前尝试过,但随后画布缩小以匹配滚动条,粘贴到NW角... – Ysch

+0

我认为将滚动条嵌入画布中并不是一个好主意 - 您在画布上绘制的任何内容都可能会最终在滚动条下。另外,OP混合包装和网格的方式非常好。你可以(也应该!)将它们混合到一个应用中,而不是在同一个小部件中。 –

+0

终于明白了!我将自己传递给滚动条而不是self.canvas。感谢指示方向。 – Ysch

相关问题