Hallo zusammen,
habe in den letzten zwei Tagen, die Empfehlung von Hyperion versucht umzusetzen.
Habe das Ganze auf den Kopf gestellt und nichts gelassen, wie es war.
Meiner Meinung, ist die Funktionsweise, benutzerfreundlich und logisch aufgebaut.
Die Funktionen:
- keysym_input
- drift_event
- nosign_event
- input_work
- control_output
habe ich so ausgearbeitet, um diese mit einer eigenen Klasse in einem externen Modul betreiben zu können.
Mit diesem Modul, ist dann nicht nur eine ComboBox zu steuern, sondern auch ein Entry-Feld ohne ComboBox.
Hier mal mein Code, mit der Bitte um Input!
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
from tkinter import ttk
class ComboBox:
def __init__(self, mylist):
self.mylist = mylist
self.combo_check = {'??' : '??'}
self.drift = {'Right' : +1, 'Left' : -1}
self.none_check = {'Return' : 'Return', 'Delete' : 'Delete',
'KP_Enter' : 'KP_Enter', 'KP_Delete' : 'KP_Delete',
'BackSpace' : 'BackSpace'}
self.key2utf = {'adiaeresis' : 'ä', 'Adiaeresis' : 'Ä',
'odiaeresis' : 'ö', 'Odiaeresis' : 'Ö', 'udiaeresis' : 'ü',
'Udiaeresis' : 'Ü', 'ssharp' : 'ß', 'space' : ' '}
self.len_imput = 0
self.len_combo = 0
self.key_input = ''
self.selected = False
# create the self.combo box
self.combo = ttk.Combobox()
self.combo.bind('<<ComboboxSelected>>', self.control)
self.combo.bind('<KeyRelease>', self.control)
self.combo.bind('<Button-1>', self.control)
self.combo.focus_set()
# load the self.combo box with the list
self.combo['values'] = self.mylist
# pack the widgets vertically in this order
self.combo.pack()
self.combo.mainloop()
def keysym_input(self, wert, key_input, combo_get):
"""
Verarbeite den Tastenwert aus event.keysym.
- Dictionary key2utf, wandelt bei den Selbstlauten 'ÄäÖöÜüß',
den Ausgabewert von event.keysym in ein UTF-Zeichen um.
- Dictionary combo_check, vergleicht bei selektierten Wert der
ComboBox, den Ausgabewert von event.keysym.
"""
if len(wert) == 1:
return wert
result = self.key2utf.get(wert)
if result:
return result
result = self.combo_check.get(wert)
if result:
if key_input != combo_get:
return combo_get
else:
return key_input
result = self.none_check.get(wert)
if result:
return combo_get
return None
def drift_event(self, event, key_input, combo_get):
"""
Überprüfe die Cursor-Richtung mit event.keysym durch
Dictionary self.drift.
- Verarbeite die Cursor-Bewegung (Right, Left)
und aktualisiere keyinput.
"""
check = self.drift.get(event)
if not check:
return None
if len(combo_get) > len(key_input):
start = key_input[:len(key_input)+check]
end = combo_get[len(start):len(start)+1]
key_input = start + end
return key_input
def nosign_event(self, event, key_input, len_input, combo_get,
len_combo):
"""
Überprüfe event.keysym mit Dictionary self.none_check.
- Verarbeite Delete, KP_Delete, BackSpace
"""
check = self.none_check.get(event)
if not check:
return None
if check == 'BackSpace':
if len(key_input) > 1:
key_input = key_input[:len(key_input)-1]
else:
key_input = ''
return key_input
elif check == 'Delete' or check == 'KP_Delete':
if len(key_input) > 1:
key_input = key_input[:len(key_input)+1]
else:
key_input = key_input[:1]
return key_input
def input_work(self, wert, key_input, selected):
"""
Überprüfe Eingabewert mit der Auswahlliste
- Postiver Eingabewert, Übergabe des Eingabewertes
- Negativer Eingabewert, letzter Eingabewert wird gelöscht
Rückgabewert:
- Ergebnis, <ComboboxSelected> == True
"""
try:
if len(wert) == 1:
if selected:
return wert, False
else:
return (key_input + wert), False
else:
return wert, True
except TypeError:
if key_input:
return key_input[:-1], False
else:
return ''
def control_output(self, key_input):
"""
Vergleiche die Eingabewerte mit der Auswahlliste.
- Postiver Eingabewert, Ausgabe des Listenergebnisses
- Negativer Eingabewert, letzter Eingabewert wird gelöscht
"""
try:
check = [item for item in self.mylist
if item.upper().startswith(key_input.upper())][0]
return check, key_input
except IndexError:
return '', key_input[:-1]
def control(self, event):
"""
Überwache die Eingabewerte durch Tastatur und Maus.
Funktionen:
- keysym_input
- drift_event
- nosign_event
- input_work
- control_output
"""
if self.key_input != '':
self.len_imput = len(self.key_input)
if self.combo.get() != '':
self.len_combo = len(self.combo.get())
result = self.keysym_input(event.keysym, self.key_input,
self.combo.get())
drift = self.drift_event(event.keysym, self.key_input,
self.combo.get())
if drift:
self.key_input = drift
eventcheck = self.nosign_event(event.keysym, self.key_input,
self.len_imput, self.combo.get(), self.len_combo)
if eventcheck:
self.key_input = eventcheck
self.combo.set(eventcheck)
return
if not result:
return
self.key_input, self.selected = self.input_work(result,
self.key_input, self.selected)
self.combo.set(self.combo.get().strip())
combo, self.key_input = self.control_output(self.key_input)
self.combo.set(self.key_input)
if combo != '':
self.combo.set(combo)
def main():
L = ['aaaaaa', 'abbbbb', 'aaabbb', 'acabbb', 'bbbbbb', 'cccccc',
'vvvvvv', 'wwwwww', 'xxxxxx', 'yyyyyy', 'yywyyy', 'zzzzzz', ]
ComboBox(L)
if __name__ == "__main__":
main()