2016-03-03 4 views
1

При использовании этого вызова функции в TkInter:TkInter create_rectangle() фиксированный размер

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). Но тогда еще одна проблема заключается в том, что положение верхнего левого угла прямоугольника тоже меняется в зависимости от ширины контура.

Любое решение, позволяющее точно определить, где будет располагаться прямоугольник, с точки зрения верхнего левого угла и определения конечного размера?

EDIT: Включенная фотография. Обратите внимание, как прямоугольник «начинается» на двух совершенно разных позициях из окна (по оси X), нарисовал красную линию для справки.

enter image description here

Я бы очень хотел, чтобы верхний левый угол остается неизменным, независимо от моей ценности outline_width. Или, по крайней мере, уметь знать, как сильно он сдвинется вправо, чтобы я мог изменить свои координаты, чтобы компенсировать это.

Благодаря

+0

«Положение верхнего левого угла режанки изменяется также в зависимости от ширины контура« Как это меняется? – Goyo

+0

Не могу точно сказать, как это меняется, потому что это то, о чем мой вопрос (я не знаю), но это ясно. Например, если я использую outline_width из 3, координата, в которой мой прямоугольник «начинается» по x, составляет 9, а если я использую outline_width из 10, он «начинается» в 5. Кажется, не имеет смысла me (измеряется относительно действительно фиксированной точки на окне). – Yannick

+0

Это интересно - я не думаю, что я бы назвал эту ширину контура так же, как и ширину границы, потому что кажется, что половина ширины штриха находится внутри границы, а половина - снаружи. Возможно, вам придется катиться самостоятельно, если вы хотите более предсказуемого поведения ... –

ответ

2

Прямоугольник представляет собой 2D-диапазон. Без контура create_rectangle обрабатывает первые 2 числа как начальные значения, а следующие 2 - как значения остановки, как и для функции 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, но иногда кажется, что он отключен.)

'''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) 

Результаты (с использованием одного числа для обоих х и у)

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

Очень хороший ответ за то, что потратил некоторое время, помогая мне и даже придумывая правильные смещения, спас мне драгоценное время. Я бы хотел, чтобы TK вел себя так, как указано в DOC, было бы намного лучше, но опять же, как вы сказали, за этим стоит, может быть, несколько микрофонов, если его вызывающие API GDI или другие родные файлы Windows. – Yannick

1

Картины показывают, что x0, y0 снижение на width/2 и x1, y1 увеличиваются на ту же сумму. Теперь похоже, что холст рисует точные пиксели без какого-либо сглаживания, поэтому потребуется некоторое округление, и я не уверен, как это будет сделано. Если вам нужна точность пикселей, вам может потребоваться пробная версия и ошибка, чтобы получить все в нужном месте.

+0

Для python 3 или python 2 с последующим импортом целочисленного деления используйте '//' вместо '/'. Из моих экспериментов, сообщенных в моем ответе, увеличение 'x1, y1' равно' (width + 1) // 2. –

Смежные вопросы