KeyCodes vereinheitlichen zwischen Tkinter / PyGame

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich würde gern eingaben zwischen Tkinter, PyGame vereinheitlichen. Normale Zeichen sind ja nicht das Problem.
Aber was ist mit z.B. ENTER, Backspace, ESC, Shift usw. ?

Hab ein paar Tests gemacht. Sieht so aus, das PyGame event.scancode und Tkinter event.keycode die selben Werte liefern. (Zumindest bei meinen getesteten Tasten):

Code: Alles auswählen

"""
Display PyGame Keycodes
=======================

1 - Char: u'1' - scancode: dez.: 10, hex: $0a - key: dez.: 49,  hex: $31
2 - Char: u'2' - scancode: dez.: 11, hex: $0b - key: dez.: 50,  hex: $32
a - Char: u'a' - scancode: dez.: 38, hex: $26 - key: dez.: 97,  hex: $61
A - Char: u'A' - scancode: dez.: 38, hex: $26 - key: dez.: 97,  hex: $61
b - Char: u'b' - scancode: dez.: 56, hex: $38 - key: dez.: 98,  hex: $62
B - Char: u'B' - scancode: dez.: 56, hex: $38 - key: dez.: 98,  hex: $62
@ - Char: u'@' - scancode: dez.: 24, hex: $18 - key: dez.: 113, hex: $71

Space       - Char: u' '    - scancode: dez.: 65,  hex: $41 - key: dez.: 32,  hex: $20
ENTER       - Char: u'\r'   - scancode: dez.: 36,  hex: $24 - key: dez.: 13,  hex: $0d
ESC         - Char: u'\x1b' - scancode: dez.: 9,   hex: $09 - key: dez.: 27,  hex: $1b
Shift left  - Char: u''     - scancode: dez.: 50,  hex: $32 - key: dez.: 304, hex: $130
Shift right - Char: u''     - scancode: dez.: 62,  hex: $3e - key: dez.: 303, hex: $12f
Backspace   - Char: u'\x08' - scancode: dez.: 22,  hex: $16 - key: dez.: 8,   hex: $08
Up          - Char: u''     - scancode: dez.: 111, hex: $6f - key: dez.: 273, hex: $111
Down        - Char: u''     - scancode: dez.: 116, hex: $74 - key: dez.: 274, hex: $112
Left        - Char: u''     - scancode: dez.: 113, hex: $71 - key: dez.: 276, hex: $114
Right       - Char: u''     - scancode: dez.: 114, hex: $72 - key: dez.: 275, hex: $113
"""

import sys
import pygame

screen = pygame.display.set_mode((560, 384))
pygame.display.set_caption("Keycodes Example")


def verbose_value(value):
    return "dez.: %i, hex: $%02x" % (value,value)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            print " --- END --- "
            sys.exit()

        if event.type == pygame.KEYDOWN:
            print event
            char = event.unicode
            scancode = event.scancode
            key = event.key

            print "Char: %s - scancode: %s - key: %s" % (
                repr(char),
                verbose_value(scancode),
                verbose_value(key),
            )
            print

Code: Alles auswählen

"""
Display Tkinter Keycodes
========================

1 - Char: '1' - keycode: dez.: 10, hex: $0a
2 - Char: '2' - keycode: dez.: 11, hex: $0b
a - Char: 'a' - keycode: dez.: 38, hex: $26
A - Char: 'A' - keycode: dez.: 38, hex: $26
b - Char: 'b' - keycode: dez.: 56, hex: $38
B - Char: 'B' - keycode: dez.: 56, hex: $38
@ - Char: '@' - keycode: dez.: 24, hex: $18

Space       - Char: ' '    - keycode: dez.: 65,  hex: $41
ENTER       - Char: '\r'   - keycode: dez.: 36,  hex: $24
ESC         - Char: '\x1b' - keycode: dez.: 9,   hex: $09
Shift left  - Char: ''     - keycode: dez.: 50,  hex: $32
Shift right - Char: ''     - keycode: dez.: 62,  hex: $3e
Backspace   - Char: '\x08' - keycode: dez.: 22,  hex: $16
Up          - Char: ''     - keycode: dez.: 111, hex: $6f
Down        - Char: ''     - keycode: dez.: 116, hex: $74
Left        - Char: ''     - keycode: dez.: 113, hex: $71
Right       - Char: ''     - keycode: dez.: 114, hex: $72
"""

import sys
import Tkinter


def verbose_value(value):
    return "dez.: %i, hex: $%02x" % (value,value)


class TkKeycodes(object):
    def __init__(self):
        self.root = Tkinter.Tk()
        self.root.title("Keycodes Example")
        self.root.geometry("+500+300")

        self.root.bind("<Key>", self.event_key_pressed)

        self.root.update()

    def event_key_pressed(self, event):
        char = event.char # pressed character (KeyPress, KeyRelease)
        keycode = event.keycode # keycode of the pressed key (KeyPress, KeyRelease)
        print "Char: %s - keycode: %s" % (
            repr(char),
            verbose_value(keycode),
        )

    def mainloop(self):
        self.root.mainloop()

tk_keys = TkKeycodes()
tk_keys.mainloop()
Ich frage mich allerdings:
A.) Sollte ich generell auf keycode/scancode setzten, oder besser event.char/event.unicode bei "normalen" Zeichen nehmen?
B.) Sind die codes einheitlich, egal. welche Tastatur / Betriebssystem?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mache nun das:

Code: Alles auswählen

char_or_code = event.unicode or event.scancode
und nutzte das dann als keys für mein "mapping":

Code: Alles auswählen

...
    "X": ((0, 5),), # X
    "Y": ((1, 5),), # Y
    "Z": ((2, 5),), # Z
    0x6f: ((3, 5),), # UP
    0x74: ((4, 5),), # DOWN
    0x71: ((5, 5),), # LEFT
    0x72: ((6, 5),), # RIGHT
    " ": ((7, 5),), # " " (Space)

    "\r": ((0, 6),), # ENTER
    0x6e: ((1, 6),), # CLEAR - $6e is "Home" / "Pos 1" button
    "\x1b": ((2, 6),), # BREAK - $09 is "Escape" button

    0x32: ((7, 6),), # SHIFT (shift left)
    0x3e: ((7, 6),), # SHIFT (shift right)

Weiß einer ob man immer die selben codes erhält, egal ob unter windows/linux oder deutsche/englische tastatur usw.?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Nein, natürlich sind diese Codes nicht überall gleich. Deswegen gibt es ja die Abstraktion mit den Konstanten.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@jens: die Scan-Codes mit den Tasten-Zeichen in einen Topf zu werfen, ist nicht so toll, da es ja doch Überschneidungen gibt. Die Scan-Codes haben sich seit der Einführung der IBM-PC-Tastatur nicht mehr geändert und sind für alle IBM-PC-kompatiblen Rechner und deren Nachfolgern die selben. Es sind nur ein paar Tasten hinzugekommen.
MACs haben traditionell natürlich eine ganz andere Scan-Code-Zuordnung, verschiedene Workstations wieder eine andere.

Welches Zeichen auf die jeweilige Taste gemalt ist, ist wieder etwas anderes. Für verschiedene Sprachen gibt es unterschiedliche Tastenbelegungen und über Xchrmap kann man sowieso jeder Taste wieder eine ganz andere Bedeutung zuordnen.

Ich vermute mal, dass man heutzutage an den physikalischen Scan-Code gar nicht mehr ran kommt, sondern dass die Tastenevents nur einen Virtuellen-Scan-Code bekommen, der schonmal vom Tastaturtreiber in irgendeiner Form angepasst wurde. Je nach Layout wird dieser Scan-Code dann in ein Zeichen umgewandelt, und nur darüber weiß man, wo tatsächlich ein 'A' auf der Taste steht, oder auch nicht.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wobei ich auch nicht wirklich wissen will, wo ein eingetipptes "A" herkommt :-) deswegen nutzte ich vorzugsweise das eingegebene Zeichen. Aber z.B. bei Shift links oder rechts, ohne eine zusätzlich gedrückte taste, gibt es kein Zeichen.

Auf konstanten zurück zu greifen ist allerdings ein guter Hinweis. Wenn ich aber tkinter und pygame vereinheitliche will, muss ich noch eine Übersetzung machen, was?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: Ja, da müsste man dann eine Abbildung zwischen Tk- und Pygame-Konstanten machen, bzw. eine Abbildung jeweils von beiden auf den eigenen Konstantensatz.
Antworten