Das Verwirrendste wird wohl der sich nicht bewegende Cursor sein. Tkinter bietet entsprechende Funktionen an, um diesen zu bewegen, allerdings habe ich diese der Einfachheit halber weggelassen.
Als Hilfe: Füg mal "print(self.user_input)" als erste Zeile der Methode validate() ein. Merkst du was?
Wenn du beispielsweise mehrmals "a" drückst, besteht die Zeichenfolge aus "aaaaa". Gibst du jetzt z.B. "b" ein, ergibt sich "aaaaab". Da jedoch keiner deiner Listeneinträge damit startet, wird das "b" ignoriert und es steht weiterhin "aaaaaa" als Ausgabe. Nicht vorgesehene Zeichen sind quasi komplett unsichtbar, wobei es anscheinend noch schwerer wird, da sich der Cursor nicht bewegt. Könnte man reinmachen, wollte jetzt aber erstmal nur das Teil erklären
ComboBox - Aktualisierung im Ausgabefeld
Ja, das mit dem nichtbewegenden Cursor ist sehr verwirrend.
Ich probiere Deinen Vorschlag mit "print(self.user_input)" aus.
Bei "aaaaa" und der Eingabe von ' b', daß dann die ganze Reihe gelöscht wird und 'b' als Anfangsbuchstabe in einer neuen Suche fortgeführt wird, ist nicht wie ich es mir vorstelle.
Es kann zur Folge "aaaaa" weitere Möglichkeiten geben, daher finde ich daß die Ausgabe von 'self.cobo.get()' unterbrochen wird und nur auf die letzte Möglichkeit von "aaaaa" der Cursor zurück geht. Als Benutzer ist mir dann klar, daß es mit "aaaaab" kein Resultat gibt.
Die ComboBox muß letztendlich benutzerfreundlich und nicht verwirrend sein.
Ich probiere Deinen Vorschlag mit "print(self.user_input)" aus.
Bei "aaaaa" und der Eingabe von ' b', daß dann die ganze Reihe gelöscht wird und 'b' als Anfangsbuchstabe in einer neuen Suche fortgeführt wird, ist nicht wie ich es mir vorstelle.
Es kann zur Folge "aaaaa" weitere Möglichkeiten geben, daher finde ich daß die Ausgabe von 'self.cobo.get()' unterbrochen wird und nur auf die letzte Möglichkeit von "aaaaa" der Cursor zurück geht. Als Benutzer ist mir dann klar, daß es mit "aaaaab" kein Resultat gibt.
Die ComboBox muß letztendlich benutzerfreundlich und nicht verwirrend sein.
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!
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()
Das mit dem set, ist mir noch nicht klar?
Ich habe jetzt ein Modul zum ansteuern der ComboBox erstellt:
Was dann noch im Modul ComboBox übrigbleibt ist dies:
Ich habe jetzt ein Modul zum ansteuern der ComboBox erstellt:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
class List2Result(object):
def __init__(self):
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
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 ('', False)
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 main():
return
wert = 'a'
key_input = 'abc'
combo_get = ''
result = List2Result().keysym_input(wert, key_input, combo_get)
print(result)
if __name__ == "__main__":
main()
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
from tkinter import ttk
from help2listresult import List2Result
class ComboBox:
def __init__(self, mylist):
self.mylist = mylist
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 control(self, event):
"""
Überwache die Eingabewerte durch Tastatur und Maus.
Funktionen aus Modul help2listresult (Class: List2Result):
- keysym_input
- drift_event
- nosign_event
- input_work
"""
if self.key_input != '':
self.len_imput = len(self.key_input)
if self.combo.get() != '':
self.len_combo = len(self.combo.get())
# keysym_input
result = List2Result().keysym_input(event.keysym, self.key_input,
self.combo.get())
# drift_event
drift = List2Result().drift_event(event.keysym, self.key_input,
self.combo.get())
if drift:
self.key_input = drift
# nosign_event
eventcheck = List2Result().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
# input_work
self.key_input, self.selected = List2Result().input_work(result,
self.key_input, self.selected)
self.combo.set(self.combo.get().strip())
# control_output
try:
check = [item for item in self.mylist
if item.upper().startswith(self.key_input.upper())][0]
return self.combo.set(check), self.key_input
except IndexError:
self.key_input = self.key_input[:-1]
return self.combo.set(self.key_input), self.key_input
def main():
L = ['aaaaaa', 'abbbbb', 'aaabbb', 'acabbb', 'bbbbbb', 'cccccc',
'vvvvvv', 'wwwwww', 'xxxxxx', 'yyyyyy', 'yywyyy', 'zzzzzz', ]
ComboBox(L)
if __name__ == "__main__":
main()
Du solltest eine Menge verwenden, weil du das Dictionary wie eine Menge verwendest. Wenn der Wert zu einem Schlüssel immer identisch ist (oder alle Werte des Dictionary), dann sind die Werte überflüssig und du brauchst nur die Schlüssel. Und ein Dictionary nur mit Schlüsseln ist eine Menge.Nobuddy hat geschrieben:Das mit dem set, ist mir noch nicht klar?
Das Leben ist wie ein Tennisball.
Hallo EyDu,
meinst Du so etwas in der Art?
meinst Du so etwas in der Art?
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x
a = {'4711' : ['abc', 'asd', '10', 'löä'],
'4612' : ['abc', 'asd', '5', 'löä'],
'4513' : ['abc', 'asd', '7', 'löä']}
key_input = input()
try:
print([a.get(x) for x in set(a) if x.startswith(key_input)][0])
except IndexError:
print('Kein Ergebnis für diese Zeichenfolge!')
Nein, du verwendest doch nicht einmal eine Menge. Ich meine das:
Und statt
dann eben einfach
Da fällt mir auf: "result" ist ein sehr seltsamer Name, wenn es sich nicht um ein Ergebnis handelt.
Bzw. statt
dann
Code: Alles auswählen
self.none_check = set(['Return', 'Delete' : 'Delete', 'KP_Enter', 'KP_Delete', 'BackSpace'])
Code: Alles auswählen
result = self.none_check.get(wert)
if result:
return combo_get
return None
Code: Alles auswählen
if wert in self.none_check:
return combo_get
return None
Bzw. statt
Code: Alles auswählen
check = self.none_check.get(event)
if not check:
return None
Code: Alles auswählen
if event not in self.none_check:
return None
#else:
# check = event
Das Leben ist wie ein Tennisball.