Seite 1 von 1

Lexikon als Gui

Verfasst: Mittwoch 5. Juni 2019, 12:46
von solver
Hallo,

ich möchte gern ein kleines Lexikon als Gui programmieren.
Es soll ungefähr so aussehen wie auf dem Bild.

Bild

Auf den Buttons links sollen die Wörter des Lexikons angezeigt werden.
Bei Klick auf einen Button soll im Textfeld rechts die Erklärung zum geklickten Button geladen werden.
Die Erklärung soll man über das Textfeld ändern können.

Momentan sieht mein Code folgendermaßen aus:

Code: Alles auswählen

from tkinter import *
import functools


class Application(Frame):
    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_textanzeige()
        self.create_objects()

    def create_textanzeige(self):
        self.textanzeige = Text(height=2, width=50)
        self.textanzeige.grid()

    def create_objects(self):
        self.objects = {"zebra": "Das Zebra lebt in Afrika. \nEs ist ein Saeugetier.",
                        "koala": "Der Koala lebt in Australien. \nEr ist ein Beuteltier.",
                        "Känguru": "Das Känguru lebt in Australien und ist ein Beuteltier."
                        }

        for wort, erklaerung in self.objects.items():
            but = Button(self, text=wort, command=functools.partial(self.textanzeige.insert, END, erklaerung))
            but.grid()


root = Tk()
root.title("Lexikon")
root.geometry("410x200")

app = Application(root)

root.mainloop()
Aktuelles Problem:

Jedes Mal, wenn ein Button angeklickt wird, wird die jeweilige Erklärung geladen, ohne dass die vorherige Erklärung gelöscht wird.
Aber eigentlich soll die vorherige Erklärung gelöscht werden und die neue Erklärung eingefügt werden.
Wie kann ich dies erreichen?



Vielen Dank fürs Lesen und Helfen im Voraus

solver

Re: Lexikon als Gui

Verfasst: Mittwoch 5. Juni 2019, 13:47
von __blackjack__
`insert` heisst halt „einfügen“, und nicht „ersetzen”. Ersetzen gibt's auf `Text`-Widgets nicht, das muss man sich aus zwei anderen Operationen basteln. Hier steht was es so für Methoden gibt auf `Text`-Widgets: https://effbot.org/tkinterbook/text.htm

Widgets sollten sich nicht selbst anordnen, das ``self.grid()`` gehört nicht in die `__init__()`. Dafür ist das auslagern der Erzeugung der GUI in extra Methoden nicht wirklich sinnvoll.

Sternchen-Importe sind Böse™. `tkinter` wird üblicherweise als ``import tkinter as tk`` importiert, und die Werte aus dem Modul dann über ``tk.Button`` usw. angesprochen.

Re: Lexikon als Gui

Verfasst: Mittwoch 5. Juni 2019, 13:49
von __deets__
Hast du dir mal die Methoden von tkinter.Text angeschaut? Ich bin sicher da findest du etwas: http://effbot.org/tkinterbook/text.htm

Re: Lexikon als Gui

Verfasst: Mittwoch 5. Juni 2019, 18:34
von solver
Vielen Dank für die Hinweise auf die Methoden.
Ich habe nun einen Weg gefunden, wie ich eine Funktion mit den beiden Methoden und den jeweiligen Argumenten definieren kann. Diese wird durch Klick auf den Button als command ausgeführt.

sieht jetzt folgendermaßen aus:

Code: Alles auswählen

import tkinter as tk
import functools


class Application(tk.Frame):
    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_textanzeige()
        self.create_objects()

    def ersetzen(self, erklaerung):
        self.textanzeige.delete(1.0, tk.END)
        self.textanzeige.insert(tk.END, erklaerung)

    def create_textanzeige(self):
        self.textanzeige = tk.Text(height=2, width=50)
        self.textanzeige.grid()

    def create_objects(self):
        self.objects = {"zebra": "Das Zebra lebt in Afrika. \nEs ist ein Saeugetier.",
                        "koala": "Der Koala lebt in Australien. \nEr ist ein Beuteltier.",
                        "Känguru": "Das Känguru lebt in Australien und ist ein Beuteltier."
                        }

        for wort, erklaerung in self.objects.items():
            self.temp_text = erklaerung
            but = tk.Button(self, text=wort, command=functools.partial(self.ersetzen, erklaerung))
            but.grid()


root = tk.Tk()
root.title("Lexikon")
root.geometry("410x200")

app = Application(root)

root.mainloop()
Als nächstes werde ich einen Weg suchen, damit nach Änderung der Erklärung im Textfeld die neue Erklärung gespeichert wird.
Wenn ich bei einem Problem Hilfe brauche, melde ich mich wieder.

Re: Lexikon als Gui

Verfasst: Mittwoch 5. Juni 2019, 19:19
von Sirius3
Ein Tk-Element sollte sich nicht selbst platzieren, weil Du jetzt auf grid festgelegt bist, obwohl das übergeordnete Fenster vielleicht besser per pack anordnen möchte.
Was soll self.temp_text?

Re: Lexikon als Gui

Verfasst: Mittwoch 5. Juni 2019, 20:36
von __blackjack__
@solver: Beim `Text`-Widget gibst Du gar nicht an wo das angezeigt werden soll, was dazu führt das es direkt im Hauptfenster landet, was ziemlich undurchsichtig ist.

Code: Alles auswählen

#!/usr/bin/env python3
from functools import partial
import tkinter as tk


class Application(tk.Frame):
    
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.objects = {
            'Zebra': 'Das Zebra lebt in Afrika. \nEs ist ein Saeugetier.',
            'Koala': 'Der Koala lebt in Australien. \nEr ist ein Beuteltier.',
            'Känguru': 'Das Känguru lebt in Australien und ist ein Beuteltier.',
        }
        frame = tk.Frame(self)
        for wort, erklaerung in self.objects.items():
            tk.Button(
                frame, text=wort, command=partial(self.ersetzen, erklaerung)
            ).pack(side=tk.TOP)
        frame.pack(side=tk.LEFT, anchor=tk.NW)
        
        self.textanzeige = tk.Text(self, height=2, width=50)
        self.textanzeige.pack(side=tk.LEFT, anchor=tk.NW)

    def ersetzen(self, erklaerung):
        self.textanzeige.delete(1.0, tk.END)
        self.textanzeige.insert(tk.END, erklaerung)


def main():
    root = tk.Tk()
    root.title('Lexikon')

    app = Application(root)
    app.pack()

    root.mainloop()


if __name__ == '__main__':
    main()

Re: Lexikon als Gui

Verfasst: Donnerstag 6. Juni 2019, 12:15
von solver
Okay. Das ist für mich als Anfänger erstmal viel neues. Da werde ich mich genauer damit beschäftigen, wenn ich die Zeit habe.
Der Unterschied ob man .grid() oder .pack() verwendet ist anscheinend ziemlich wesentlich.
Was den allgemeinen Aufbau einer Gui angeht, kann ich auch noch viel lernen.