Oop: -methode grid / automatisches ausführen von cmd / Hilfe

Fragen zu Tkinter.
Antworten
Astraioz

Hallo,
erstmal großes Lob an das Forum hier man bekommt gute Tipps :).
Nun zum Problem, ich habe mich nun mal an Oop gemacht und stoße auf folgende Probleme:

- Wenn ich .grid() benutze öffnet sich das Tkinter Fenster überhaupt nicht mehr

- Wenn ich das Programm ausführe wird automatisch der command vom Button ausgeführt

Das Ergebnis:

Code: Alles auswählen

Benutzer oder Passwort falsch
Mein Code sieht so aus:

Code: Alles auswählen

import Tkinter as tk
import sqlite3 as sql

connection = sql.connect('database.db')
cursor = connection.cursor()

def query(cmd):
    cursor.execute(cmd)

query('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY,name CHAR[30],password CHAR[30],score TEXT)')

class LoginUI(object):
    def __init__(self, master):

        self.master = master
        self.master.geometry('300x150')
        
        self.welcome_label = tk.Label(master, text='Willkommen')
        self.welcome_label.pack(side=tk.TOP)
        
        self.entry1_text = tk.Label(master, text='Benutzername: ')
        self.entry1_text.pack()
        self.entry1 = tk.Entry(master, bg="#C0C0C0")
        self.entry1.pack()
        self.entry2_text = tk.Label(master, text='Passwort: ')
        self.entry2_text.pack()
        self.entry2 = tk.Entry(master, bg="#C0C0C0")
        self.entry2.pack()

        self.login_button = tk.Button(master, text='Login', command=self.login(self.entry1, self.entry2))
        self.login_button.pack()
        self.close_button = tk.Button(master, text='Quit', command=master.destroy)
        self.close_button.pack()

    def login(self, entry1, entry2):
        self.username = entry1.get()
        self.passwort = entry2.get()
        query('SELECT password FROM users WHERE name = "'+self.username+'"')
        self.password = cursor.fetchall()
        if self.password == self.passwort:
            print 'Erfolgreich eingeloggt'
        else:
            print 'Benutzer oder Passwort falsch'
            self.entry1['bg'] = '#FF0000'
            self.entry2['bg'] = '#FF0000'

        
def main():
    root = tk.Tk()
    login = LoginUI(root)
    root.mainloop()


if __name__ == '__main__':
    main()
Würde auch nicht schaden wenn ihr mir so Tipps geben würdet :)
LG
Astraioz
Zuletzt geändert von Astraioz am Sonntag 10. März 2013, 22:04, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Der Grund warum das Aufgerufen wird liegt daran, dass du in

Code: Alles auswählen

        self.login_button = tk.Button(master, text='Login', command=self.login(self.entry1, self.entry2))
``self.login()`` aufrufst, was natürlich dazu führt dass, uh, ``login`` ausgeführt wird. Du willst dort aber keine Funktion aufrufen, sondern eine Funktionsreferenz übergeben.

Füge diesen Import hinzu:

Code: Alles auswählen

from functools import partial
und baue dann diese Zeile so um:

Code: Alles auswählen

        self.login_button = tk.Button(master, text='Login', command=partial(self.login, self.entry1, self.entry2))
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Astraioz

@Leonidas: Erstmal Danke für die schnelle Antwort.

Ich verstehe nicht ganz warum ich diese direkt Aufrufe? Sollte doch erst aufgerufen werden wenn ich den Button drücke.


Kannst du mir auch weiterhelfen warum .grid() nicht funktioniert?
BlackJack

@Astraioz: Wenn man eine Funktion aufruft und dabei Ausdrücke als Argumente übergibt, dann werden die *vor* dem eigentlichen Aufruf ausgewertet und deren Ergebnis wird dann übergeben. Und Du hattest da als Ausdruck nun mal den Funktionsaufruf. Wobei das mit dem `partial()` zwar funktioniert, aber unsinnig ist, denn die Eingabefelder sind ja Attribute auf dem Objekt, also kann die andere Methode darauf zugreifen ohne sie übergeben zu bekommen.

`grid()` funktioniert. Wenn es bei Dir nicht funktioniert, dann machst Du etwas falsch. Was das ist, kann man ohne Quelltext nur erraten. Vielleicht das Du `grid()` und `pack()` in gleichen Elternwidget vermischst?

Den `geometry()`-Aufruf würde ich weg lassen. Die Grösse des Fensters ergibt sich ja aus dem Inhalt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Astraioz hat geschrieben:Ich verstehe nicht ganz warum ich diese direkt Aufrufe? Sollte doch erst aufgerufen werden wenn ich den Button drücke.
Naja, du hast da einen Funktionsaufruf, wenn du

Code: Alles auswählen

def bar():
    return 42

def foo(a=bar()):
    print(a)
anschaust, sollte es eigentlich klar sein was passiert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten