Как мне запрограммировать нажатие двойной клавиши, чтобы немодифицирующая клавиша в моей программе работала как клавиша-модификатор?
Я пишу программу ввода текста, которая включает в себя гораздо больше символов, чем доступно на стандартной клавиатуре. Для этого мне нужно преобразовать некоторые из букв алфавита в клавиши-модификаторы CTRL + A. Например, F + J будет выводить a
, Печатание f тогда j медленно для пользователя, мне нужно, чтобы они могли одновременно нажимать f и j и получать один вывод. Это нормально (даже предпочтительнее), если некоторые нормальные функции клавиатуры останавливаются во время работы программы.
Я посмотрел в Pygame Keydown, но кажется, что он имеет функции для увеличения повторения клавиш, а не остановки вывода клавиш. Pyglet также возможен, но у него нет точной документации о том, как я мог бы сделать дополнительные клавиши-модификаторы. Единственный способ, которым я могу понять, - это постоянно сканировать всю клавиатуру, чтобы увидеть, нажаты ли какие-либо клавиши, но это не определит порядок нажатия клавиш и создаст ошибки для пользователя, так как пользователь нажимает клавишу f j будет читаться так же, как пользователь нажимает j, затем f, и мне нужно, чтобы система воспринимала только комбинацию f и j как нажатие клавиши.
2 ответа
Вот простой код для быстрой печати клавиш, написанных на Python 2. Его можно легко модифицировать в соответствии с вашими потребностями:
import pygame, sys
pygame.init()
screen = pygame.display.set_mode([500,500])
clock = pygame.time.Clock()
combokeys = []
timer = 0
ACCEPTABLE_DELAY = 30 #0.5 seconds
while 1:
clock.tick(60)
timer += 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if timer <= ACCEPTABLE_DELAY:
combokeys.append(event.unicode)
else:
combokeys = [event.unicode]
timer = 0
print combokeys
Я не смог протестировать этот код (работает на школьном компьютере), поэтому, пожалуйста, сообщите мне в комментариях, если что-то не работает, чтобы я мог это исправить.
Вы можете изменить значение, указанное для ACCEPTABLE_DELAY, чтобы изменить задержку, прежде чем что-то будет считаться другой комбинацией клавиш. Задержка должна составлять (ACCEPTABLE_DELAY/60) секунд.
Вот версия Pyglet о том, как вы можете это сделать.
Я основал его на общем классе GUI, который я часто использую здесь, на SO, потому что он модульный и его легче построить, не запутавшись в коде после 40 строк.
import pyglet
from pyglet.gl import *
key = pyglet.window.key
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(800, 800, fullscreen = False)
self.x, self.y = 0, 0
#self.bg = Spr('background.jpg')
self.output = pyglet.text.Label('',
font_size=14,
x=self.width//2, y=self.height//2,
anchor_x='center', anchor_y='center')
self.alive = 1
self.pressed = []
self.key_table = {213 : 'a'}
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_key_release(self, symbol, modifiers):
if symbol == key.LCTRL:
pass # Again, here's how you modify based on Left CTRL for instance
## All key presses represents a integer, a=97, b=98 etc.
## What we do here is have a custom key_table, representing combinations.
## If the sum of two pressed matches to our table, we add that to our label.
## - If no match was found, we add the character representing each press instead.
## This way we support multiple presses but joined ones still takes priority.
key_values = sum(self.pressed)
if key_values in self.key_table:
self.output.text += self.key_table[key_values]
else:
for i in self.pressed:
self.output.text += chr(i)
self.pressed = []
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
elif symbol == key.LCTRL:
pass # Modify based on left control for instance
else:
self.pressed.append(symbol)
def render(self):
self.clear()
#self.bg.draw()
self.output.draw()
self.flip()
def run(self):
while self.alive == 1:
self.render()
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
x = main()
x.run()
Это может выглядеть как много кода, особенно для ответа Pygame. Но вы также можете сократить это до ~15 строк, но, опять же, код станет запутанным, если вы попытаетесь использовать его дальше.
Надеюсь, это работает. Теперь я не продумал математическую схему этого вопроса. Возможно, две дублированные комбинации клавиш приведут к тому же значению, что и другое представление ключа, просто замените ключи словаря. 213
например, с ключом кортежа, таким как self.key_table = {(107, 106) : 'a'}
который будет представлять K+J
Несколько преимуществ:
- Нет необходимости отслеживать задержки
- Быстро и отзывчиво
- Любую клавишу можно превратить в модификатор или сопоставить с пользовательскими раскладками клавиатуры, что означает, что вы можете превратить QWERTY в DWORAK только для этого приложения. Не уверен, почему вы этого хотите, но эй.. Это не мое дело:D
- Переопределяет ввод с клавиатуры по умолчанию, поэтому вы можете перехватывать их и делать с ними все, что захотите.
Редактировать: одна интересная особенность - зарегистрировать каждую клавишу вниз, но заменить последний символ объединенной комбинацией. Опять же, это все ручные работы, поскольку клавиатура не предназначена для представления двойных клавиш, и это скорее графический идея.. Но было бы круто:)