Suche in GUI optimieren

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
TightPhysics
User
Beiträge: 5
Registriert: Dienstag 20. April 2021, 00:33

meine Suche in der GUI stockt extrem und sorgt für schlechte Benutzererfahrung. Wenn ich threading für einzelne Methoden benutze werden die Befehle nicht ordnungsgemäß ausgeführt:

Code: Alles auswählen


lass ScrollableRadiobuttonFrame(customtkinter.CTkScrollableFrame):
    def __init__(self, master, item_list, command=None, **kwargs):
        super().__init__(master, **kwargs)

        self.app_instance = master
        self.command = command
        self.item_list = item_list
        self.radiobutton_variable = customtkinter.StringVar()
        self.radiobutton_list = []

        self.app_instance.search_entry = customtkinter.CTkEntry(
            self.app_instance,
            placeholder_text="Search...",
            width=300
        )
        self.app_instance.search_entry.grid(row=2)
        self.app_instance.search_entry.bind("<KeyRelease>", self.check)
        self.update_list(self.item_list)

    def check(self, event):
        typed = self.app_instance.search_entry.get()
        print(typed)
        if typed == "":
            data = self.item_list
        else:
            data = []
            for item in self.item_list:
                if typed.lower() in item.lower():
                    data.append(item)

        self.update_list(data)

    def update_list(self, data):
        self.remove_items(self.item_list)
        for i, item in enumerate(data):
            self.add_item(item)

    def add_item(self, item):
        radiobutton = customtkinter.CTkRadioButton(self, text=item, font=customtkinter.CTkFont(size=13),
                                                   value=item,
                                                   variable=self.radiobutton_variable,
                                                   height=25, width=25)
        if self.command is not None:
            radiobutton.configure(command=self.command)
        radiobutton.grid(row=len(self.radiobutton_list), column=0, pady=(0, 10), padx=10, sticky="w")
        self.radiobutton_list.append(radiobutton)

    def remove_item(self, item):
        for radiobutton in self.radiobutton_list:
            if item == radiobutton.cget("text"):
                radiobutton.destroy()
                self.radiobutton_list.remove(radiobutton)
                return

    def remove_items(self, items):
        for item in items:
            self.remove_item(item)

    def get_checked_item(self):
        return self.radiobutton_variable.get()

Wie kriege ich die Abläufe flüssiger?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Es ist sehr ungewöhnlich (will sagen falsch), wenn ein Widget Attribute des Master-Objekts anlegt oder ändert.
In `update_list` wird i gar nicht benutzt.
`remove_item` ist sehr umständlich, weil die Liste linear durchsucht wird und in Kombination mit `remove_items` findet das dann quadratisch statt.
Dein Problem ist die update_liste-Methode, die sollte nämlich das tun, was der Name suggeriert, nur die Radio-Buttons, die sich geändert haben, ändern, und nicht alles löschen und alles neu aufbauen, denn das ist langsam.
TightPhysics
User
Beiträge: 5
Registriert: Dienstag 20. April 2021, 00:33

Okay. Mein Master objekt hat ein anderes design, weshalb ich das Widget an dieses anlegen wollte. die remove_item Methode ist tatsächlich von customtkinter in github übernommen. Daher stammt dieses Widget. Bei der Update Methode habe ich das Problem, dass ich glaube, dass ich RadioButtons löschen muss, da sich kein RadioButton ändert. Es werden lediglich die namentlich passenden herausgesucht und neu generiert. Ich könnte natürlich alle nicht passenden löschen, müsst aber bei leerem Suchinhalt wieder alle RadioButtons neu generieren. Oder gibt es eine andere Möglichkeit mit grid_remove, vielleicht?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst die Radio-Buttons auch rekonfigurieren. Und nur ueberzaehliche entfernen, oder notwendige erzeugen. Noch besser waere, die verschiedenen Mengen an Radiobuttons vorzuhalten. Oder ein anderes Widget zu benutzen, zB ein Drop-Down.
TightPhysics
User
Beiträge: 5
Registriert: Dienstag 20. April 2021, 00:33

Ich habe das Problem nun gelöst:
wie oben bereits überlegt ist es Sinnvoller die nicht passenden Items auszublenden. Damit wird am Anfang einmalig die Liste mit Radiobuttons generiert. Bei der Lösung des Ein- und Ausblendens hilft die grid_forget() Methode, die die jeweiligen Items nicht löscht sondern nur ausblendet und mit grid() und den jeweiligen Parametern wieder eingeblendet, wenn das Ergebnis zutrifft.

Danke für Eure Denkanstöße!
Antworten