【问题标题】:TkInter create_rectangle() fixed sizeTkInter create_rectangle() 固定大小
【发布时间】:2016-03-03 13:36:48
【问题描述】:

在 TkInter 中使用此函数调用时:

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

我想要一个可以预测大小的矩形。问题在于,根据outline_width,整体矩形大小会有所不同。

例如,如果我保持不变

(xsize, ysize) = (20,20)

在改变outline_width 时,我得到了奇怪的尺寸。例如 outline_width=1 给出一个 21px 的正方形,而使用 outline_width=4 给出一个 24px 的正方形。 这对我来说是个大问题,因为如果我无法预测矩形的大小(即包括轮廓在内的大小),我的整个绘图都会受到影响。

例如,看起来矩形的总 x 宽度将由 (xsize+outline_width) 确定。但另一个问题是矩形左上角的位置也因轮廓宽度而异。

任何解决方案可以准确地确定矩形在左上角的位置,并确定最终大小?

编辑:包括一张图片。请注意矩形是如何从窗口的两个完全不同的位置(在 X 轴上)“开始”的,并绘制了一条红线以供参考。

我真的希望无论outline_width 的值如何,左上角都保持不变。或者至少能够知道它会向右移动多少,这样我就可以改变我的坐标来补偿它。

谢谢

【问题讨论】:

  • “矩形左上角的位置也因轮廓宽度而异”它如何变化?
  • 无法准确告诉您它是如何变化的,因为这正是我的问题的全部内容(我不知道),但它显然确实如此。例如,如果我使用 3 的轮廓宽度,我的矩形“开始”x 方向的坐标是 9,而如果我使用 10 的轮廓宽度,它“开始”在 5。似乎没有多大意义我(相对于窗口上真正的固定点测量)。
  • 这很有趣 - 我认为我不会将其称为边框宽度,而是将其称为边框宽度,因为看起来笔画宽度的一半在边框内,一半在边框外。如果你想要一个更可预测的行为,你可能不得不自己动手......
  • @Wayne Werner 是的,将其称为“大纲”对我来说没有多大意义,我将不得不求助于由 4 个线段组成我自己的方形函数
  • @Yannick 不确定它是否会更好,但您可以考虑在您绘制的框外仅绘制 2px 大的框,轮廓宽度为 1px。

标签: python tkinter


【解决方案1】:

矩形是一个二维范围。在没有轮廓的情况下,create_rectangle 将前 2 个数字视为起始值,将接下来的 2 个数字视为终止值,与 Python 的 range(start, stop) 函数一样。具有输入 x0、y0、x1、y1 的矩形包括像素 x、y,其中 x0

添加轮廓时,NMT reference 表示“轮廓位于矩形顶部和左侧的内部,但位于底部和右侧的矩形之外。”这个参考,通常很好,在这里是错误的,至少在 3.5.1 和 tk 8.6.4 的 Windows 上。但是,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)     

【讨论】:

  • 非常好的答案非常感谢您花时间帮助我,甚至提出正确的偏移量,为我节省了宝贵的时间。但是,我希望 TK 的行为与您指出的 DOC 一样,会更好,但正如您所说,如果它调用 GDI API 或其他本机 Windows 的东西,这背后可能会有一些微不足道的问题。
【解决方案2】:

图片表明x0、y0 减少了width / 2 和x1、y1 增加了相同的数量。现在看起来画布在没有任何抗锯齿的情况下以精确的像素绘制,因此需要进行一些舍入,我不确定如何完成。如果您想要像素精度,您可能需要反复试验才能将所有内容放在正确的位置。

【讨论】:

  • 对于带有整数除法未来导入的 python 3 或 python 2,使用 // 而不是 /。根据我的实验,在我的回答中报告,x1, y1 增加是 `(width+1)//2。
猜你喜欢
  • 2017-07-09
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2012-03-17
  • 2019-01-11
  • 2011-09-27
  • 2011-08-16
  • 1970-01-01
相关资源
最近更新 更多