GUI-Dialog in Programme einbinden

Fragen zu Tkinter.
Antworten
bfm
User
Beiträge: 88
Registriert: Donnerstag 14. März 2013, 09:42

Hallo,

ich habe mit Daten aus der Zeitwirtschaft und Betriebsdatenerfassungen diverse Auswertungen programmiert. Bisher ist jede Auswertung ein eigenständiges konsolenbasiertes Pythonskript. Da jetzt auch Kollegen damit arbeiten müssen/sollen, will in alles in einer einheitlichen GUI zusammenfassen. Das Rahmenwerk mit Hauptfenster und Menüzeile steht schon. Die Programme für den Import der Daten sind auch schon integriert und funktionieren.

Bei den Programmen für die Auswertungen habe ich jetzt allerdings etwas Probleme. Diese verlangen immer nach einem Zeitraum von bis. Auf der Konsole habe ich dies immer mittels input abgefragt. Für die GUI habe ich mir jetzt eine Klasse geschrieben, die eigentlich nichts anderes macht, als ein Toplevel-Fenster mit zwei Eingabefeldern für die Daten von und bis, einem Button OK und Button Abbrechen zu erstellen. Die Daten-Felder werden standardmäßig mir Vorschlagswerten aus der Datenbank gefüllt.

Code: Alles auswählen

import tkinter
import tkinter.ttk as ttk
import datumzeit
import fibu_datum

#global DATENBANK für Test
DATENBANK = '../daten/bdezw.sqlite'


class zeitraum(object):
    def __init__(self, parent, DATENBANK):
        print(DATENBANK)
        self.datenbank = DATENBANK
        self.datum_von = ''
        self.datum_bis = ''
        self.eingabefenster_erstellen(parent)

    #Maske erstellen
    def eingabefenster_erstellen(self, parent):
        self.rahmen = tkinter.Toplevel(parent)
        self.rahmen.title('Monat aendern')
        self.rahmen.geometry('300x150+400+400')

        #Zeitraum aus Datenbank vorschlagen
        self.zeitraum = datumzeit.monat_auslesen(self.datenbank)
        print('Datenbank: ', self.zeitraum, self.zeitraum[0][0], self.zeitraum[0][1])

        self.von_label = ttk.Label(self.rahmen, text='von')
        self.von_label.grid(row=0, column=0, padx=10, pady=10)

        self.von_var = tkinter.StringVar(value=self.zeitraum[0][0])
        self.von_datum  = ttk.Entry(self.rahmen, width=10, textvariable=self.von_var)
        self.von_datum.grid(row=0, column=1, padx=10, pady=10)

        self.bis_label = tkinter.Label(self.rahmen, text='bis')
        self.bis_label.grid(row=1, column=0, padx=10, pady=10)

        self.bis_var = tkinter.StringVar(value=self.zeitraum[0][1])
        self.bis_datum  = ttk.Entry(self.rahmen, width=10, textvariable=self.bis_var)
        self.bis_datum.grid(row=1, column=1, padx=10, pady=10)

        self.ok = ttk.Button(self.rahmen, text='OK', command=self.monat_aendern)
        self.ok.grid(row=3, column=0, padx=10, pady=10)

        self.abbruch = ttk.Button(self.rahmen, text='Abbruch', command=self.rahmen.destroy)
        self.abbruch.grid(row=3, column=1, padx=10, pady=10)

        self.rahmen.grid()

        self.rahmen.bind('<Escape>', self.esc_rahmen)
        self.von_datum.bind('<Return>', self.enter_von_datum)
        self.bis_datum.bind('<Return>', self.enter_bis_datum)

        self.von_datum.focus_set()
        print('Eingabefelder', self.von_var.get(), self.bis_var.get())

    def enter_von_datum(self, event):
        print(event.keysym)
        self.von_var.set(fibu_datum.datum_str2db(self.von_var.get()))
        if fibu_datum.datum_db_ok(self.von_var.get()):
            event.widget.event_generate('<Tab>')

    def enter_bis_datum(self, event):
        print(event.keysym)
        self.bis_var.set(fibu_datum.datum_str2db(self.bis_var.get()))
        if fibu_datum.datum_db_ok(self.bis_var.get()):
            event.widget.event_generate('<Tab>')

    def monat_aendern(self):
        datumzeit.monat_aendern(self.datenbank, self.von_var.get(), self.bis_var.get())
        self.rahmen.destroy()
#        master.destroy()

    #Escape im Fenster gedrueckt ==> Fenster schliessen
    def esc_rahmen(self, event):
        self.rahmen.destroy()
#        master.destroy()



def main():
    fenster = zeitraum(master, DATENBANK)
    print('hier')

if __name__ == '__main__':
    master = tkinter.Tk()
    master.title('Test')
    master.geometry('200x200+1+1')
    main()
    master.mainloop( )
Ich habe jetzt mal versucht, die Klasse in ein bestehendes Programm einzufügen. Irgendwie funktioniert das aber nicht so wie ich das gerne will.

Code: Alles auswählen

import sqlite3
import dialog_zeitraum


def main(parent, DATENBANK):

    dialog = dialog_zeitraum.zeitraum(parent, DATENBANK)

#    bdecon = sqlite3.connect(DATENBANK)
#   cursorbde = bdecon.cursor()

#ZW loeschen
#    cursorbde.execute('''DELETE FROM zw WHERE tag BETWEEN ? AND ?''',
#        (datumvon, datumbis))
#    print('geloeschte Saetze ZW: ', bdecon.total_changes)

#BDE loeschen
#    cursorbde.execute('''DELETE FROM bde WHERE startdatum BETWEEN ? AND ?''',
#        (datumvon, datumbis))
#    print('geloeschte Saetze BDE: ', bdecon.total_changes)
    #bdecon.commit()

#    bdecon.close()
    print('hier')

if __name__ == '__main__':
    main()
Das Toplevel erscheint, es wird aber auch gleich die Zeile 24 "print('hier')"ausgeführt, dh. der zu Testzwecken auskommentierte Code wird ja (eigentlich logischerweise) auch gleich ausgeführt. Der soll ja aber erst ausgeführt werden, wenn OK geklickt wurde. Also irgendwie muss ich den Code an die Methode heften, die beim Klicken des OK-Button ausgeführt werden soll. Irgendwie habe ich da keinen richtigen Plan, wie das üblicherweise gemacht wird.

Wäre es zB richtig, das bestehende Programm als Klasse umzuschreiben, die von der Klasse dialog_zeitraum erbt und hier dann die Methode monat_aendern mit dem richtigen Code zum Verarbeiten der Daten zu überschreiben?

Vielen Dank im Voraus!
BlackJack

@bfm: Du möchtest an der Stelle einen (modalen) Dialog schreiben. Beziehungsweise wahrscheinlich eher auf der Dialog-Basisklasse aufbauen die in der Standardbibliothek schon enthalten ist. In Python 2 ist das `tkSimpleDialog.Dialog`. Musst mal schauen wie das in Python 3 jetzt heisst.
Antworten