Я возился с холстами в TK, и у меня есть небольшой пример черного прямоугольника, следующего за курсором:
package require Tk
package require Thread
ttk::frame .c
canvas .c.card
.c.card create rectangle 0 0 1000 1000 -fill green
.c.card create rectangle 0 0 100 200 -fill black -tags card
pack .c .c.card -fill both -expand 1
proc moveCard {x y} { .c.card moveto card $x $y }
set mouseDown 0
bind . <ButtonPress> { set mouseDown 1 }
bind . <ButtonRelease> { set mouseDown 0 }
bind . <Motion> { if { $mouseDown } { moveCard %x %y; } }
Однако, когда я быстро перемещаю прямоугольник, он «рвется» — кажется, что положение прямоугольника обновляется в середине рисунка сверху вниз, поэтому верх и низ находятся в разных местах! Насколько я понимаю, это разрыв экрана, который происходит из-за перерисовки событий, не синхронизированных с частотой обновления экрана. Однако я не могу найти, как включить vsync или иначе предотвратить это. Точно ли я определил проблему, и если да, то как ее исправить?
Кстати, я на старом MacBook Pro под управлением MacOS 10.15.7 (довольно старый), и разрывов не вижу. Я знаю, что это не поможет вашей проблеме, но я подумал, что это может быть достойным источником данных.
@aMike Спасибо, полезно знать - указывает на путь просто установить TearFree на дисплей и двигаться дальше. Кажется, у различных программ есть проблемы с разрывом экрана на xorg, которых нет на других платформах!
Tk уже выполняет внутреннюю двойную буферизацию для всех виджетов (за исключением, возможно, меню), но ничего не знает о том, когда следует выполнять дублирование буфера, чтобы избежать разрыва; это зависит от систем нижнего уровня (например, Xserver), обрабатывающих все это.
Похоже, это можно улучшить. Я не уверен, какие уведомления будут задействованы, если таковые имеются, но обычно они не будут доступны сценариям, поскольку это вещи, которые на самом деле являются областью движка рисования.
Общее решение — «двойная буферизация» вашего холста. Я ничего не знаю о TCL/TK, но вам стоит поискать именно этот термин. Альтернативой является рисование всего в версии «растрового изображения» TCL/TK, а затем рисование всего растрового изображения сразу.