Как я могу запрограммировать два одновременных события нажатия клавиш в tkinter, чтобы перемещать элемент холста по диагонали с помощью словаря событий нажатия клавиш?

Ниже приведен код для перемещения квадрата вокруг холста. Он захватывает события нажатия клавиши со стрелкой и перемещает квадрат вверх, вниз, влево и вправо. Одновременное нажатие двух стрелок (например, вверх и влево) не приводит к диагональному перемещению. Вместо этого он перемещается только в одном из двух необходимых направлений.

Как я могу изменить этот код, чтобы обеспечить гладкое диагональное движение квадрата. Спасибо за ваше время.

from tkinter import * x = 10 y = 10 a = 100 b = 100 direction = None def move(): global x_vel global y_vel global direction if direction is not None: canvas1.move(rect, x_vel,y_vel) window.after(33,move) def on_keypress(event): global direction global x_vel global y_vel direction, x_vel, y_vel = dir_vel[event.keysym] def on_keyrelease(event): global direction direction = None dir_vel = { "Left": ("left", -5, 0), "Right": ('right', 5, 0), "Down": ('down', 0, 5), "Up": ('up', 0, -5),} window = Tk() window.geometry("400x200") move() #canvas and drawing canvas1=Canvas(window, height = 200, width = 400) canvas1.grid(row=0, column=0, sticky=W) coord = [x, y, a, b] rect = canvas1.create_rectangle(*coord, outline="#fb0", fill="#fb0") #capturing keyboard inputs and assigning to function window.bind_all('<KeyPress>', on_keypress) window.bind_all('<KeyRelease>', on_keyrelease) 

2 Solutions collect form web for “Как я могу запрограммировать два одновременных события нажатия клавиш в tkinter, чтобы перемещать элемент холста по диагонали с помощью словаря событий нажатия клавиш?”

Как я могу запрограммировать … события

Часть программы: Tkinter может сам по себе генерировать UI-событие, без внешнего стимула, фактически происходящего «впереди» пользовательского интерфейса. Итак, «Как я могу запрограммировать событие» часть выполняется с помощью этого метода:

 self.event_generate( <eventNameId>, **args ) # fire STIMULUS without User-interaction # # triggers <eventNameId> # # **args allow to set <keyword>=<value> # # pairs for Event-fields, # # that are passed to anEventHANDLER # # via an-<Event>-object ... # # ref below ( not the system-assigned ones, sure ) 

Проблемы с одновременностью:

Как правило, код Tkinter / python выполняется последовательно. Нет простого способа, как создать экземпляр двух событий в тот же самый момент. Проще говоря, ваш код должен каким-то образом имитировать / обнаруживать почти одновременные события, потому что он по своей природе является последовательным процессором.

Поскольку Брайан Оукли хорошо объяснил в какой-то другой статье, UI-обнаружение должно иметь в виду, что проведение ArrowUp и / или ArrowLeft может привести в действительности к автоматически генерируемой последовательности событий UI- * вне своего контроля (ol ' дней с настройкой скорости клавиатуры с клавиатурой BIOS, отвечающей за автоматическое повторение нажатия клавиши, когда клавиатура обнаруживает нажатие клавиши нажатой … не закончится …)

Как читать входные стимулы

Tkinter имеет мощный набор методов MVC-Controller-Part для обработки (как естественно, так и искусственно «впрыскиваемых» .event_generate() ). Это будет важно для других аспектов задачи:

 # eventInstanceMethods() bear many details about click/key/time/.widget() # <event>.char on-{ <KeyPress> | <KeyRelease> } # .keysym on-{ <KeyPress> | <KeyRelease> } # .keysym_num on-{ <KeyPress> | <KeyRelease> } # .num on-{ <Mouse-1> | <Mouse-2> | ... } ? 4,5 == <MouseWheel> # .height on-{ <Configure> } # .width on-{ <Configure> } # .serial <-- system-assigned Integer # .time <-- system-assigned Integer ( .inc each msec ) # .widget <-- system-assigned <widget>-instance # .x <-- system-assigned <Event>-in-<widget>-mouse-location.x # .y <-- system-assigned <Event>-in-<widget>-mouse-location.y # .x_root <-- system-assigned <Event>-on-<Screen>-mouse-location.x # .y_root <-- system-assigned <Event>-on-<Screen>-mouse-location.y 

Для обнаружения таких событий Tkinter оснащен следующими методами:

 # |<<_aNamedEVENT_>>|<<______________________________aHANDLER>>| # |or | | # |<<_VirtualEVENT>>| | # | | | .bind( "<KeyPress-Left>", self.__doWidgetBoundTaskSpecificHANDLER ) .bind_class( "Button", "<KeyPress-Left>", self.__doClass_BoundTaskSpecificHANDLER ) .bind_all( "<KeyPress-Left>", self.__doApplicBoundTaskSpecificHANDLER ) 

Как программировать для перемещения со словарем

Это проблема с зеленым полем и, если она ограничена, чтобы использовать словарь в MVC-Model-Part, вы идете. После вышеназванных проблем ваш Finite-State-Automaton (FSA) для направления (на основе не только пары { <KeyPress> | <KeyRelease> } триггеров слепых состояний-переходов, но и последовательности ключей с близостью TimeDOMAIN обработка и с расширенной, одноключевой и с двумя ключами грамматикой состояния (nil, Left , Up , Right , Down , Left && Up , Left && Dn , Right && Up , Right && Dn } и обработка) немного возрастает сложный, но для первого прототипа вы можете просто изменить правила назначения словаря и начать с чего-то вроде этого:

 def on_keypress( event ): # keeping the Globals-style, global direction # however shall be rather global x_vel # implemented in a Class-based global y_vel # manner direction = dir_vel[event.keysym][0] # ref. remark on more complex FSA x_vel += dir_vel[event.keysym][1] y_vel += dir_vel[event.keysym][2] def on_keyrelease( event ): global direction global x_vel global y_vel x_vel -= dir_vel[event.keysym][1] y_vel -= dir_vel[event.keysym][2] if abs( x_vel * y_vel ) < 0.1: direction = None # ref. remark on more complex FSA 

Я просто играл с одновременными нажатиями клавиш, и оказывается, что они до 10 мс друг от друга, поэтому, если вы проверите, что две кнопки нажаты в течение 20 мс друг от друга, вы можете рассматривать их одновременно. Я уверен, что есть более элегантное решение.

  • Текст в поле ввода очищается при нажатии Tkinter
  • Python tkinter с календарем ttk
  • Как передать аргументы команде Button в Tkinter?
  • TKinter - виджеты не «прилипают» в рамке с использованием сетки
  • Удаление значка TK в окне Tkinter
  • Входной виджет Tkinter с Overrideredirect и полноэкранным
  • Попытка добавить простое изображение в ярлык
  • Способ воспроизведения видеофайлов в Tkinter?
  •  
    Interesting Posts for Van-Lav

    Методы без тестирования в тестовой среде Python

    Преобразование строки в dict?

    Порядок аргументов ключевого слова и не ключевого слова

    Иерархическая диаграмма пирога / пончика из Pandas DataFrame с использованием bokeh или matplotlib

    Ошибка загрузки PYTHON DLL

    Как проверить, существует ли что-то в базе данных postgresql с помощью django?

    Несколько выходных файлов для потоковой передачи Hadoop с помощью Python Mapper

    Запустите скрипт MATLAB из python + pass args

    Python Dictionary: удаление строки из кортежа (WHICH – это ключ.)

    Нечетное поведение при подключении к моей программе

    Python: импортировать модуль из другого каталога на том же уровне в иерархии проектов

    Как скопировать каталог и его содержимое в существующее место с помощью Python?

    Удаление данных между двойными скобками с вложенными скобками в python

    Что такое «Отображение символов типаError должно возвращать целое число …» в этом коде python?

    Bash: рекурсивно записывать строку в файл из максимального столбца

    Python - лучший язык программирования в мире.