2014-02-26 51 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