簡體   English   中英

Tkinter畫布自動調整大小

[英]Tkinter canvas resizing automatically

所以在回答這個問題的過程中,我遇到了Tkinter的一些奇怪的行為。 我有一個類來調整Canvas實例的大小以及在其上繪制的任何小部件。 但是,當我運行代碼時,無論初始窗口尺寸如何,窗口都會不斷擴展,直到它填滿整個屏幕。 發生這種情況后,窗口的行為與預期完全一致,正確調整對象的大小。 該窗口僅在啟動時展開以填充屏幕。

通過閱讀Tkinter文檔,我可以相信這可能是特定於平台的(盡管我沒有任何證據)。

我的問題是:為什么會這樣? 我怎么能阻止它?

代碼如下:

from Tkinter import *

# a subclass of Canvas for dealing with resizing of windows
class ResizingCanvas(Canvas):
    def __init__(self,parent,**kwargs):
        Canvas.__init__(self,parent,**kwargs)
        self.bind("<Configure>", self.on_resize)
        self.height = self.winfo_reqheight()
        self.width = self.winfo_reqwidth()

    def on_resize(self,event):
        # determine the ratio of old width/height to new width/height
        wscale = float(event.width)/self.width
        hscale = float(event.height)/self.height
        self.width = event.width
        self.height = event.height
        # resize the canvas 
        self.config(width=self.width, height=self.height)
        # rescale all the objects tagged with the "all" tag
        self.scale("all",0,0,wscale,hscale)

def main():
    root = Tk()
    myframe = Frame(root)
    myframe.pack(fill=BOTH, expand=YES)
    mycanvas = ResizingCanvas(myframe,width=850, height=400, bg="red")
    mycanvas.pack(fill=BOTH, expand=YES)

    # add some widgets to the canvas
    mycanvas.create_line(0, 0, 200, 100)
    mycanvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
    mycanvas.create_rectangle(50, 25, 150, 75, fill="blue")

    # tag all of the drawn widgets
    mycanvas.addtag_all("all")
    root.mainloop()

if __name__ == "__main__":
    main()

我們已經建立了highlightthickness的一種選擇Canvas ,是針對此行為的罪魁禍首,並將其設置為0修復該問題。

這就是為什么(我認為)它會發生的原因:

來自http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

配置 窗口小部件更改大小(或在某些平台上的位置)。 新大小在傳遞給回調的事件對象的width和height屬性中提供。

這是Canvas子類的精簡版:

class ResizingCanvas(Canvas):
    def __init__(self,parent,**kwargs):
        Canvas.__init__(self,parent,**kwargs)
        print self.winfo_reqwidth(),self.winfo_reqheight() #>>>854, 404
        self.bind("<Configure>", self.on_resize)

    def on_resize(self,event):
        self.width = event.width   #>>>854
        self.height = event.height #>>>404
        self.config(width=self.width, height=self.height)

所以, <Configure>應該像這樣運行:

  1. 檢測調整大小
  2. 通話功能
  3. 將畫布設置為新大小

但它正在這樣做:

  1. 檢測調整大小
  2. 通話功能
  3. 將畫布設置為新大小
  4. 檢測調整大小,重復

3到4之間發生了什么? 好吧,Canvas被設置為一個新的大小(之前的大小+4),但之后,highlightthickness將實際大小更改為+4,這將在無限循環中觸發<Configure>直到屏幕寬度被擊中它打破了。

此時,可以進行正常的調整大小,因為它只有一個尺寸可以處理(組合的高光和畫布大小),並且它正常運行。 如果你添加了一個按鈕來調整畫布大小並在畫布停止展開后按下它,它會調整大小,然后再次變得怪異並開始擴展。

我希望能解釋一下。 我不是100%確定這是100%正確,所以如果有人有更正,請隨意。

我認為最初的問題是on_resize()的遞歸行為,它綁定到Configure事件,resize()也調用“self.config(width = self.width,height = self.height)” - 這將觸發配置事件再次。 刪除“self.config(width = self.width,height = self.height)”將解決問題。

顯然設置“highlightthickness = 0”也解決了問題 - 我猜測窗口布局管理器有一些魔法檢測窗口大小沒有變化因此停止以遞歸方式調用on_resize()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM