HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Searching Combobox drop-down list

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
searchingdropdownlistcombobox

Problem

I've created a Combobox GUI that allows the user to search through the Combobox by entering a letter on the keyboard. If user enter letter 'L' it will search through the Combobox drop-down list for the first occurrence of a word that starts with letter 'L'.

Please let me know if I could have made my findInBox method better. Do you know of a way to search through the drop-down list while it is open?

```
import tkinter
tk = tkinter

from tkinter import StringVar, Label, Button
from tkinter import font
from tkinter.ttk import Combobox

class Parking_Gui(tk.Frame):

def __init__(self):
"""Sets up the window and widgets"""
tk.Frame.__init__(self)

self.myfont = font.Font(family="Calibri", size=11, weight="normal")

self.master.geometry("315x125")
self.master.title("MSU PARKING APP")
self.master.rowconfigure(0, weight = 1)
self.master.columnconfigure(0, weight = 1)
self.grid(sticky = 'NW')

# Label for the parking lots
self.LotLabel = tk.Label(self, text = "MSU Parking", font=self.myfont)
self.LotLabel.grid(row = 0, column = 0)

# Combo Box for parking lots
self._ComboValue = tk.StringVar()
self._LotCombo = Combobox(self, textvariable=self._ComboValue,
state='readonly', height = '6',
justify = 'center', font=self.myfont)

# List of parking lots
self._LotCombo['values']=('ARTX', 'BURG', 'CLAY_HALL', 'GLAB',
'HAMH_HUTC', 'HHPA', 'JVIC', 'LIBR','PLSU',
'POST', 'PROF', 'STEC', 'STRO_NORTH',
'STRO_WEST', 'TROP')
self._LotCombo.grid(row = 0, column = 1)

# Button to open parking diagram
self._button = tk.Button(self, text = "Open", font=self.myfont)
self._button.bind('', self._runParkingLot)
self._button.grid(row = 0, column = 2)

Solution

Imports

There is a more idiomatic way of doing

import tkinter
tk = tkinter


it is import tkinter as tk.

You’re also importing StringVar, Label and Button from tkinter but still calling them using the tk namespace. Either remove the import line or remove the tk. part when creating such objects.

Same for font, you import it from tkinter and use it only for font.Font. Either do from tkinter.font import Font and call it using only Font or call it with tk.font.Font. All in all, it’s more a matter of consistency than saving on typing.

ComboBox management

First of, you should define your values as a constant somewhere. Either at the top-level of the file or as a class attribute. That way you could re-use it in both __init__ and findInBox without having to define it twice.

Secondly, your alpha is pretty much string.ascii_uppercase. No need to redefine it again.

Lastly, you’d be better of using a combination of for and enumerate to iterate over your different values. Both because a for loop makes the intent of iteration clearer, and the index management is simpler using enumerate:

import tkinter as tk

from tk.font import Font
from tk.ttk import Combobox

from string import ascii_uppercase

class Parking_Gui(tk.Frame):

    PARKING_LOTS = ('ARTX', 'BURG', 'CLAY_HALL', 'GLAB', 'HAMH_HUTC',
                    'HHPA', 'JVIC', 'LIBR', 'PLSU', 'POST', 'PROF',
                    'STEC', 'STRO_NORTH', 'STRO_WEST', 'TROP')

    def __init__(self):
        ...
        self._LotCombo['values'] = Parking_Gui.PARKING_LOTS
        ...

    ...
    def findInBox(self, event):
        keypress = event.char.upper()

        if keypress in ascii_uppercase:
            for index, lot_name in enumerate(Parking_Gui.PARKING_LOTS):
                if lot_name[0] >= keypress:
                    self._LotCombo.current(index)
                    break


PEP8 & PEP257

Small improvements in readability but:

  • class names should be TitleCase not Title_Snake_Case



  • functions and variable names should be snake_case and not TitleCase or camelCase. (And constants like PARKING_LOTS in UPPER_SNAKE_CASE.)



  • new lines in docstring should be indented at the same level than the start of the """, not their end. Multi-line docstrings should also have the closing """ on their own line.

Code Snippets

import tkinter
tk = tkinter
import tkinter as tk

from tk.font import Font
from tk.ttk import Combobox

from string import ascii_uppercase


class Parking_Gui(tk.Frame):

    PARKING_LOTS = ('ARTX', 'BURG', 'CLAY_HALL', 'GLAB', 'HAMH_HUTC',
                    'HHPA', 'JVIC', 'LIBR', 'PLSU', 'POST', 'PROF',
                    'STEC', 'STRO_NORTH', 'STRO_WEST', 'TROP')

    def __init__(self):
        ...
        self._LotCombo['values'] = Parking_Gui.PARKING_LOTS
        ...

    ...
    def findInBox(self, event):
        keypress = event.char.upper()

        if keypress in ascii_uppercase:
            for index, lot_name in enumerate(Parking_Gui.PARKING_LOTS):
                if lot_name[0] >= keypress:
                    self._LotCombo.current(index)
                    break

Context

StackExchange Code Review Q#112104, answer score: 6

Revisions (0)

No revisions yet.