2016-03-03 90 views
1

當使用Tkinter的此函數調用:Tkinter的create_rectangle()固定大小

canvas.create_rectangle(canvas.create_rectangle(x0, y0, x0+xsize, y0+ysize, 
    outline="black", width=outline_width) 

我想要一個rectange我可以預測的大小。問題是,根據outline_width,整個矩形大小會有所不同。

例如,如果我保持不變

(xsize, ysize) = (20,20) 

,同時改變outline_width,我得到了奇怪的尺寸。例如,outline_width=1給出了21px的正方形,而使用outline_width=4給出了24px的正方形。 對於我來說,這是一個相當棘手的問題,因爲如果我無法預測矩形的大小(即包含輪廓的大小),我的整個圖形都會受到影響。

它看起來像矩形的總x寬度例如將由(xsize+outline_width)確定。但是接下來的另一個問題是,rectange的左上角位置也會因輪廓寬度而異。

任何解決方案可以準確確定矩形在左上角的位置,並確定最終尺寸?

編輯:包括一張圖片。注意矩形在窗口的兩個完全不同的位置(在X軸上)「開始」,畫出一條紅線供參考。

enter image description here

我真的想了左上角保持不變,無論我的outline_width價值。或者至少能夠知道它會向右移動多少,所以我可以改變座標以補償它。

感謝

+0

「rectange的左上角位置也因輪廓寬度而異」它是如何變化的? – Goyo

+0

不能準確地告訴你它是如何變化的,因爲那正是我的問題所有關於(我不知道),但它顯然是。例如,如果我使用outline_width爲3,那麼矩形「開始」x方向上的座標爲9,而如果我使用10的outline_width,則「開始」爲5.似乎沒有多大意義我(相對於窗口上的一個真正的固定點來衡量)。 – Yannick

+0

這很有趣 - 我認爲我不認爲我會將這個輪廓寬度稱爲邊界寬度,因爲它似乎是筆劃寬度的一半在邊界內,而一半在外部。如果你想要一個更可預測的行爲,你可能不得不推出自己的... –

回答

2

矩形是一個2D範圍。沒有大綱,create_rectangle將前兩個數字視爲起始值,將後兩個視爲停止值,就像Python的範圍(開始,停止)函數一樣。具有輸入x0,y0,x1,y1的矩形包括像素x,y,其中x0爲< = x < x1和y0 < = y < y1。大小是x1 - x0 y1 - y0像素。

當添加輪廓時,NMT reference表示「輪廓位於矩形的頂部和左側,但位於矩形的底部和右側。」這個參考,通常很好,在這裏是錯誤的,至少在Windows 3.5.1和tk 8.6.4。但是,create_rectangle行爲可能取決於操作系統的本地矩形窗口小部件。如果是這樣,我想知道。

在我的系統中,上面的規則對於1的邊界是正確的,但每個大綱圖層的添加會交替添加哪些行添加到內部和外部。使用一個好的放大鏡和下面的代碼,我確定了各種輪廓寬度的屏幕矩形的開始和結束值。 (我看着使用.bbox方法,但它似乎有時被關閉1。)

'''find actual coordinates of canvas rectangle''' 

import tkinter as tk 
root = tk.Tk() 

def report(event): 
    print(event.x, event.y) 

c = tk.Canvas(root) 
c.grid() 
w = 0 
c.create_rectangle(100, 100, 200, 200, outline='red', fill='yellow',width=0) 
c.bind('<Motion>', report) 

結果(使用x和y一個數)

w start stop 
0 100 200 
1 100, 201 
2 99, 201 
3 99, 202 
10 95, 205 

所需的校正是w//2開始和(w+1)//2爲停止。下面一行應該產生矩形,對於任何寬度小於矩形的最窄尺寸的一半的整體而言是相同的。

c.create_rectangle(100+(w//2), 100+(w//2), 200-(w+1)//2, 200-(w+1)//2, 
        fill='yellow', outline='red', width=w)  
+0

非常好的答案非常感謝花了一些時間幫助我,甚至提出了正確的補償,爲我節省了寶貴的時間。不過,我希望傳統知識會像你指出的DOC那樣行事,會好得多,但是正如你所說,如果它的調用GDI API或其他本地窗口的東西可能會有一些微不足道的東西。 – Yannick

1

這些照片表明,x0y0減少由width/2x1y1增加相同的量。現在它看起來像畫布中沒有任何抗鋸齒畫出確切的像素,所以一些舍入將是必要的,我不知道它將如何完成。如果你想要像素的準確性,你可能需要一些試驗和錯誤,讓一切都在正確的地方。

+0

對於具有整數除法未來導入的python 3或python 2,請使用''而不是'/'。從我的實驗中,在我的答案中報告,'x1,y1'增加是'(width + 1)// 2。 –