OptionMenu mit überlanger Liste

Fragen zu Tkinter.
Antworten
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,

bei einem OptionMenu, muß ich eine längere Liste zur Auswahl ausgeben.
Das Problem ist, daß ich an die unteren Auswahlzeilen nicht heran komme und wenn ich versuche mit der Maus zu scrollen, wird eine y-beliebige Zeile dabei ausgewählt.

Hier mal ein kleines und funktionierendes Beispiel:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x

import tkinter as tk
import tkinter.messagebox

my_win = tk.Tk()

frame = tk.Frame(my_win)
frame.pack(side='top', expand=True)

def beispiel():
    var = tk.StringVar()
    L = ['aaaaaa', 'bbbbbb', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc', 'cccccc',
        'uuuuuu', 'vvvvvv', 'wwwwww', 'xxxxxx', 'yyyyyy', 'zzzzzz', ]
    # Optionmenu
    canvas = tk.Canvas(frame, bd=0)
    canvas.grid(row=0, column=0, sticky=tk.NSEW)

    optionmenu = tk.OptionMenu(canvas, var, *L, command=cbOption)
    optionmenu.grid(row=0, column=0, ipadx=100)

def cbOption(wert):
    return wert

beispiel()
my_win.mainloop()


Hoffe, Ihr könnt mir da weiterhelfen?

Grüße Nobuddy
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,

nach weiteren unzähligen Recherchen, bin ich auf diesen Thread gestoßen:http://www.python-forum.de/viewtopic.php?f=18&t=9601Ich denke, daß ich hier meine Lösung finde!

Grüße Nobuddy
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Ein anderes Beispiel das ttk gebraucht:

Code: Alles auswählen

''' ttk_combobox3.py
exploring the Tkinter expansion module ttk combobox
tested with Python276, Python333 and Tkinter 8.5
ene
'''

try:
    # Python27
    import Tkinter as tk
    import ttk
except ImportError:
    # Python31 and higher
    import tkinter as tk
    import tkinter.ttk as ttk

def selection_changed(event):
    """a combo box item has been selected, show the item"""
    s = "You selected %s" % combo.get()
    root.title(s)

pasta_list = [
'Spaghetti',
'Vermicelli',
'Bucatini',
'Fettuccine',
'Linguine',
'Lasagne',
'Cavatappi',
'Manicotti',
'Macaroni',
'Penne',
'Rigatoni',
'Ziti',
'Farfalle',
'Spatzen',
'Orzo'
]

root = tk.Tk()
# window geometry is width x height + x_offset + y_offset
root.geometry("340x120+320+200")
root.title('Select a pasta from the combo box')

combo = ttk.Combobox()
# position the combobox
combo.place(x=10, y=10)
# bind selection to an action
combo.bind('<<ComboboxSelected>>', selection_changed)

# sort the pasta list
pasta_list = sorted(pasta_list)
# load the combo box with the pasta list
combo['values'] = pasta_list

# set the initial pasta
combo.set(pasta_list[0])

root.mainloop()

Zuletzt geändert von Anonymous am Freitag 20. Juni 2014, 11:18, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Atomkraftwerkaktienbesitzer
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo Ene Uran,

sorry für meine späte Rückmeldung!
Bin durch einen anderen Thread auch auf tkinter.ttk gestoßen, welches mir mehr zusagt als tix.

Mein Testcode sieht so aus:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# For Python3.x

import tkinter as tk
import tkinter.ttk as ttk
 
def action(event):
    """
    a combo box item has been selected, do some action
    """

    if var.get() != '':
        check = False
        for x in L:
            if x.startswith(var.get()):
                combo.set(x)
                check = True
        if not check:
            combo.set('')
    else:
        var.set(combo.get())


def output(event):
    var.set(combo.get())
    print(combo.get())
        

my_win = tk.Tk()

frame = tk.Frame(my_win)
frame.pack(side='top', expand=True)

var = tk.StringVar()
# create a label
entry = tk.Entry(textvariable=var, bg='white')
entry.bind('<KeyPress>', action)
entry.bind('<Return>', output)
entry.focus_set()
# create the combo box
combo = ttk.Combobox()
combo.bind('<<ComboboxSelected>>', action)

L = ['aaaaaa', 'abbbbb', 'aaabbb', 'acabbb', 'bbbbbb', 'cccccc',
    'vvvvvv', 'wwwwww', 'xxxxxx', 'yyyyyy', 'yywyyy', 'zzzzzz', ]

# load the combo box with the list
combo['values'] = L
 
# pack the widgets vertically in this order
entry.pack(fill='both', expand='yes')
combo.pack()

my_win.mainloop()
Die Funktion 'action', habe ich so gestaltet, daß die Combo-Box zu Eingabe des Entry-Feldes ein passendes Ergebnis liefert, wenn
die Reihenfolge des Entry-Feldes mit dem Anfang des Listeninhaltes identisch ist.

Folgender Fehler konnte ich allerdings noch nicht beheben.
Bei Eingabe des ersten Zeichen in das Entry-Feld, wird dieses nicht bei der Funktion 'aktion' berücksichtigt.
Erst beim zweiten Zeichen, wird ein Ergebnis in der Combo-Box-Ausgabe ausgegeben.

Mein Ziel, wäre daß das Eingabefeld automatisch mit dem ersten Ergebnis vervollständigt wird und bei jeder neuen weiteren Zeicheneingabe, wieder aktualisiert wird. Dabei wäre es ideal, wenn das vervollständigte Ergebnis markiert wäre, um so eine bessere Unterscheidung zwischen der Realeingabe und dem vervollständigten Ergebnis sichtbar zu machen.
Vielleicht kann mir das jemand von den Python-Profis beantworten, ob dies so überhaupt möglich ist und wenn ja, was dafür weiter notwendig ist?

Grüße Nobuddy
Antworten