Button wird zu früh ausgeführt :(

Fragen zu Tkinter.
Antworten
Ojisan
User
Beiträge: 6
Registriert: Freitag 29. Oktober 2010, 15:13

Hallo zusammen!

Ich bin neu hier... und auch neu in der Programmierung! Habe aber den Spass daran entdeckt und "spiele" seit ein paar Tagen mit Python rum.

Nun hänge ich super Anfänger bei einem Problem seit 2 Tagen fest. Ich habe ein kleines Beispiel Programm geschrieben (inhaltlich macht es keinen grossen Sinn).

Da habe ich eine Schieberegler eingebaut. Mit einem Submit Button. Beim drücken des Buttons soll das Resultat auf dem Fenster 'main' angezeigt werden.

Nun führt das Programm das schon aus bevor ich den Button drücke und darum ist das Resultat auch 0 und bleibt 0.

Kann mir hier einer einen Tip geben?

Viiiieln Dank!

Gruss
Sascha

Hier der Code:

Code: Alles auswählen

import tkinter

def positiv():
    popup = tkinter.Tk()
    popup.title("Prosit")
    popup.geometry("500x80+200+200")
   
    antwort = tkinter.Label(popup, font = "verdana 18 bold", text="Super! zum Wohl!")
    
    b6 = tkinter.Button(popup, font = "verdana", text = "Ende", command = popup.destroy)
    b6.place(x=250, y=70, anchor="s")
    antwort.pack()

    popup.mainloop()



def submit_res(wert):
        anzeige = str(wert)
        resultat = tkinter.Label(main, font = "verdana 12 bold", text="Anzahl Geschmackspunkte: " + anzeige)
        resultat.place(x=250, y=80, anchor="center")


def vote():
    
    vote = tkinter.Tk()
    vote.title("vote for taste")
    vote.geometry("190x250+900+300")
    
    scalewert = tkinter.IntVar()
        
    vote_scale = tkinter.Scale(vote, width =20, length=200,
                               orient="vertical", from_=0, to=100,
                               resolution=10, tickinterval=20, label="Geschmackspunkte",
                               variable=scalewert)
  
    vote_scale.pack()
    b5 = tkinter.Button(vote, text = "submit", command = submit_res(scalewert.get()))
    b5.pack()
    vote.mainloop()


def negativ():
    antwort = tkinter.Label(main, font = "verdana 10 bold", text="Tja... Schade...")
    antwort.place(x=250, y=80, anchor="center")
    

main = tkinter.Tk()
main.title('Weintest')
main.geometry("500x400+300+180")

welcome = tkinter.Label(main, anchor ="center", font = "verdana", text="Willkommen Gast!\n Möchten Sie ein Glas Wein?")
welcome.place(x = 250, y=30, anchor="center")


b = tkinter.Button(main, font = "verdana", text = "Ende", command = main.destroy)
b.place(x=250, y=350, anchor="s")

b2 = tkinter.Button(main, padx = "10", font= "verdana", text = "ja, bitte!", command = positiv)
b2.place(x=170, y=190, anchor="center")


b3 = tkinter.Button(main, padx = "10", font = "verdana", text = "nein danke!", command = negativ)
b3.place(x=350, y=190, anchor="center")


b4 = tkinter.Button(main, padx = "10", font = "verdana", text = "Vote for taste", command = vote)
b4.place(x=250, y=260, anchor="center")

main.mainloop()
Zuletzt geändert von Ojisan am Freitag 29. Oktober 2010, 17:35, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hallo,

grundätzlich musst Du Quelltext hier in code-tags stellen, sonst gehen die Einrückungen verloren! Für Python gibts noch spezielle Python-Tags, dann wird er Quellcode auch noch farbig formatiert.

Generell ist es im ürbigen keine gute Idee, sofort mit GUI-Programmierung zu beginnen, da man hier ein gutes Verständnis für OOP mitbringen sollte und dazu noch mit Nebenläuffigkeiten konfrontiert wird. Arbeite lieber ein gescheites Tutorial durch (z.B. das offizielle) und guck einfach mal in FAQ, was für Anfänger interessant sein könnte:
http://wiki.python-forum.de/FAQ#Wie_fan ... iger_an.3F
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Ojisan
User
Beiträge: 6
Registriert: Freitag 29. Oktober 2010, 15:13

Hyperion hat geschrieben:Hallo,

grundätzlich musst Du Quelltext hier in code-tags stellen, sonst gehen die Einrückungen verloren! Für Python gibts noch spezielle Python-Tags, dann wird er Quellcode auch noch farbig formatiert.

Generell ist es im ürbigen keine gute Idee, sofort mit GUI-Programmierung zu beginnen, da man hier ein gutes Verständnis für OOP mitbringen sollte und dazu noch mit Nebenläuffigkeiten konfrontiert wird. Arbeite lieber ein gescheites Tutorial durch (z.B. das offizielle) und guck einfach mal in FAQ, was für Anfänger interessant sein könnte:
http://wiki.python-forum.de/FAQ#Wie_fan ... iger_an.3F
Hallo Hyperion

Besten Dank für den Feedback. Ich werde mich gerne durch deine Links arbeiten.

Habe mich nicht gleich auf die GUI Sache gestürzt... aber die anderen Dinge haben gleich so gut geklappt, dass ich wohl etwas übermütig geworden bin. Auch bei der GUI Sache hat alles geklappt.. bis auf den letzten Punkt mit dem Button für die Auswertung des Schiebereglers :(

Na ja.. irgendwie muss es doch gehen!

Gruss
Sascha
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Hyperion hat geschrieben:Für Python gibts noch spezielle Python-Tags, dann wird er Quellcode auch noch farbig formatiert.
Kriegst du das hin?

Ich kann nur unterstreichen, was Hyperion empfohlen hat: Leg das Thema GUI nochmal zur Seite und nimm dir die Zeit für ein gutes Tutorial. Da sollte dann auch etwas drinstehen über die richtige Wahl der Bezeichner (Variablennamen etc.).
Danach oder auch parallel dazu lies dich in Tkinter ein. Dazu findest du einschlägige Links, wenn du mal ein wenig im Tkinter-Unterforum blätterst. Da wirst du dann z.B. entdecken, dass eigentlich niemand den place()-Geometriemanager benutzen mag und die Kombination mit place() und pack() auch nicht anzuraten ist. Da wirst du etwas finden über den Unterschied von Tk() und Toplevel() und dann, irgendwann demnächst, wirst du dein Problem selbst lösen können und wirst mit Gruseln auf das blicken, was du uns hier gezeigt hast.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Falls Du dann überhaupt noch Tk benutzen willst ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Ojisan
User
Beiträge: 6
Registriert: Freitag 29. Oktober 2010, 15:13

So... das Problem ist gelöst. Alles funktioniert so wie ich es wollte.

Auch wenn Euch Profis bei der Art wie den Code zusammen gebastelt habe die Haare zu berge stehen... ich freue mich über den Erfolg (ohne Hilfe) nach kurzer Zeit :)

Wünsche ein schönes Wochenende!

Gruss

Sascha
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Ojisan

Willkommen in unserem Forum. Mach nur weiter so! Jeder hat seine eigene Didaktik sich in etwas einzuarbeiten. Hier einer meiner Optimierungsvorschläge:

Code: Alles auswählen

import tkinter

def positiv():
#    popup = tkinter.Tk()
    popup = tkinter.Toplevel()
    popup.title("Prosit")
    popup.geometry("500x80+200+200")

    antwort = tkinter.Label(popup, font = "verdana 18 bold", text="Super! zum Wohl!")

    b6 = tkinter.Button(popup, font = "verdana", text = "Ende", command = popup.destroy)
    b6.place(x=250, y=70, anchor="s")
    antwort.pack()

#    popup.mainloop()

def submit_res(wert):
    anzeige = str(wert)
    resultat = tkinter.Label(main, font = "verdana 12 bold", text="Anzahl Geschmackspunkte: " + anzeige)
    resultat.place(x=250, y=80, anchor="center")

def vote():
#    vote = tkinter.Tk()
    vote = tkinter.Toplevel()
    vote.title("vote for taste")
    vote.geometry("190x250+900+300")

    scalewert = tkinter.IntVar()

    vote_scale = tkinter.Scale(vote, width =20, length=200,
                               orient="vertical", from_=0, to=100,
                               resolution=10, tickinterval=20, label="Geschmackspunkte",
                               variable=scalewert)
    vote_scale.pack()
    b5 = tkinter.Button(vote, text = "submit", command = submit_res(scalewert.get()))
    b5.pack()
#    vote.mainloop()


def negativ():
    antwort = tkinter.Label(main, font = "verdana 10 bold", text="Tja... Schade...")
    antwort.place(x=250, y=80, anchor="center")


main = tkinter.Tk()
main.title('Weintest')
main.geometry("500x400+300+180")

welcome = tkinter.Label(main, anchor ="center", font = "verdana", text="Willkommen Gast!\n Möchten Sie ein Glas Wein?")
welcome.place(x = 250, y=30, anchor="center")


b = tkinter.Button(main, font = "verdana", text = "Ende", command = main.destroy)
b.place(x=250, y=350, anchor="s")

b2 = tkinter.Button(main, padx = "10", font= "verdana", text = "ja, bitte!", command = positiv)
b2.place(x=170, y=190, anchor="center")


b3 = tkinter.Button(main, padx = "10", font = "verdana", text = "nein danke!", command = negativ)
b3.place(x=350, y=190, anchor="center")


b4 = tkinter.Button(main, padx = "10", font = "verdana", text = "Vote for taste", command = vote)
b4.place(x=250, y=260, anchor="center")

main.mainloop()
Habe:

Code: Alles auswählen

tkinter.Tk()
bis für das Hauptfenster durch:

Code: Alles auswählen

tkinter.Toplevel()
ersetzt.

Denn:

Code: Alles auswählen

tkinter.Tk()
und:

Code: Alles auswählen

mainloop()
sollten nur für das Hauptfenster benutzt werden. Dann werden beim schliessen des Hauptfensters auch eventuell geöffnete Subfenster geschlossen.
Wünsche dir weiterhin viel Spass beim Programmieren mit Python & Tkinter!

Gruss wuf :wink:
Take it easy Mates!
Ojisan
User
Beiträge: 6
Registriert: Freitag 29. Oktober 2010, 15:13

Hallo Wuf!

Besten Dank für Deine Tipps und Deine aufmunternden Worte!

Werde das gleich mal so anpassen :)

Grüsse und ein schönes Weekend!

Sascha
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok, nicht dass ich falsch verstanden wurde: Du kannst natürlich jetzt schon mit Tk arbeiten; ich wollte Dich nur darauf aufmerksam machen, dass es sinnvoll ist, die Grundlagen wirklich verstanden zu haben und auch anwenden zu können. Ansonsten kann es dann bei GUIs schnell frustrierend werden ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Ojisan
User
Beiträge: 6
Registriert: Freitag 29. Oktober 2010, 15:13

numerix hat geschrieben:
Hyperion hat geschrieben:Für Python gibts noch spezielle Python-Tags, dann wird er Quellcode auch noch farbig formatiert.
Kriegst du das hin?

Ich kann nur unterstreichen, was Hyperion empfohlen hat: Leg das Thema GUI nochmal zur Seite und nimm dir die Zeit für ein gutes Tutorial. Da sollte dann auch etwas drinstehen über die richtige Wahl der Bezeichner (Variablennamen etc.).
Danach oder auch parallel dazu lies dich in Tkinter ein. Dazu findest du einschlägige Links, wenn du mal ein wenig im Tkinter-Unterforum blätterst. Da wirst du dann z.B. entdecken, dass eigentlich niemand den place()-Geometriemanager benutzen mag und die Kombination mit place() und pack() auch nicht anzuraten ist. Da wirst du etwas finden über den Unterschied von Tk() und Toplevel() und dann, irgendwann demnächst, wirst du dein Problem selbst lösen können und wirst mit Gruseln auf das blicken, was du uns hier gezeigt hast.
Hallo Hyperion

Ich bin ja lernwillig und in den meisten Fällen auch lernfähig :)

Mein kleines Bespielprog wächst und gedeiht. Und nun wollte das ganz noch etwas schöner codieren... Sprich auch auf Deinen Input bezüglich dem place() eingehen.

Für mich war der Grund für die Verwendung des place() Geometriemanager die pixel genaue Platzierung.

Das kann ich wohl bei grid() und pack() vergessen?

Gruss und Dank für nen Tip...

Sascha

PS Tkinter ist wirklich noch speziell... wenn ich das mit den GUI Tools aus Netbeans und Objectiv-C vergleiche, welche kurz überflogen habe. :(
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi Ojisan,

auch ich habe mit Tkinter angefangen und da es zumindest für Python 2.x als quasi-Standard zählt und dabei sehr klar strukturiert ist, nutze ich es fast immer.

Als ich Deine ersten Sätze las, musste ich sofort an meine ersten Schritte mit Tkinter denken, als mir keiner explizit sagte, dass ich an die command-Ressource nur die Referenz auf die Callback-Funktion übergeben und sie keinesfalls gleich ausführen darf. Wenn man an die Callbackfunktion noch Parameter übergeben muss, dann muss man eben einen Workaround nutzen - heutzutage meist unter Verwendung des Moduls functools.

Ich wünsche Dir viel Erfolg und lass Dich von den Nörglern hier nicht das Tkinter mies machen. ;-)

LG,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich persönlich mag ja PyQt. Vor allem, weil ich mich dank eines durchdachten Ressourcen-Systems nicht manuell mit GUIs aufhalten muss, sondern ich einen Editor dafür nutzen kann und die geänderten Arrangements dynamisch in mein Script einbinden kann. Somit kann man sich auf die "Verdrahtung" der GUI-Elemente mit zugehörigen Logikfunktionen befassen.

Dasselbe gilt letztlich auch für PyGtk und vermutlich in ähnlicher Weise auch für Wx.

Tk hat den Vorteil, dass es bei Python dabei ist. Ansonsten fällt mir nicht viel ein, wieso man es nutzen sollte :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Ojisan
User
Beiträge: 6
Registriert: Freitag 29. Oktober 2010, 15:13

Ich werde mir gerne mal PyQt anschauen. Habe da den Screenshot des GUI Builder gesehen. Das schaut ja wirklich schon sehr vernünftig aus.

Gibts eine Anfänger taugliche Anleitung zur Installation auf einem Mac? Habe mir mal SID 4.11.2 und PyQT Mac 4.8.1 runter geladen. Aber die beiden Configure.py laufen leider nicht durch :(
Antworten