Seite 1 von 1

Button drücken, Zahl um 1 erhöhen

Verfasst: Mittwoch 24. Juni 2015, 20:03
von Daniel7
Hallo, ich möchte mithilfe eines Buttons eine Zahl rauf zählen lassen. Dabei soll im Hauptfenster ein Button dazu dienen, ein weiteres Fenster zu öffnen. In diesem Fenster soll ein Button dazu dienen, eine Zahl um 1 zu erhöhen.

Problem - bei Betätigung des Buttons kommt diese Fehlermeldung:

label.configure(text=klicks)
NameError: name 'label' is not defined

Code: Alles auswählen

from tkinter import *

root = Tk()
root.geometry("1350x690+0+0")

def Temperaturschwelle():

    toplevel = Toplevel()

    toplevel.geometry("1125x500+205+40")

    counter = 0

    label=Label(toplevel,text="")
    label.pack()

    def counter():

        global label
        global klicks
        label.configure(text=klicks)
        label.update()
        klicks+=1
    
    button1 = Button(toplevel, width=15, height=5, text='Schwelle erhöhen', command=counter)
    button1.place(x=0, y=0)

    button4 = Button(toplevel, width=15, height=5, command=toplevel.destroy)
    button4.place(x=0, y=315)



randomhButton = Button(root, width=15, height=5, text="Temperaturschwelle \n einstellen", command=Temperaturschwelle)
randomhButton.place(x=0, y=315)
     

quitButton = Button(root, width=15, height=5, text='Quit', command = root.destroy)
quitButton.place(x=0, y=420)


root.mainloop()

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Mittwoch 24. Juni 2015, 21:53
von BlackJack
@Daniel7: `label` ist auf Modulebene ja auch nicht definiert. Da wird es gesucht weil Du gesagt hast es sei dort (``global``). Auf ``global`` sollte man sowieso verzichten, was bei einer objektorientierten Lösung ja auch kein Problem ist und bei GUIs muss man in Python in der Regel eigene Klassen schreiben wenn man eine saubere und so verworrene Lösung haben möchte.

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 25. Juni 2015, 08:30
von Daniel7
@BlackJack: Vielen Dank für die schnelle Antwort. Programm funktioniert jetzt :D

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 25. Juni 2015, 09:55
von bwbg
Tkinter bietet "Variablen", welche sich darum kümmern, dass die jeweiligen Widgets aktualisiert werden. Das folgende Beispiel sollte das verdeutlichen:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk

class TemperatureFrame(tk.Frame):
    def __init__(self, parent, initial_temperature=0):
        super().__init__(parent)
        self.temperature_threshold = tk.IntVar(value=initial_temperature)

        tk.Label(self, textvariable=self.temperature_threshold).pack()
        tk.Button(self, text='Increase', command=self.increase).pack()
        tk.Button(self, text='Decrease', command=self.decrease).pack()
        tk.Entry(self, textvariable=self.temperature_threshold).pack()

    def increase(self):
        self.temperature_threshold.set(self.temperature_threshold.get() + 1)
        
    def decrease(self):
        self.temperature_threshold.set(self.temperature_threshold.get() - 1)
        
def main():
    root = tk.Tk()
    frame = TemperatureFrame(root, 42)
    frame.pack()
    root.mainloop()
    
if __name__ == '__main__':
    main()
Folgende Punkte solltest Du auf jeden Fall berücksichtigen:
  • Verzichte auf Sternchen-Importe (from tkinter import *)
  • Keine globalen Objekte
  • Kein Code auf Moduleebene
  • Statt des place-Layouters solltest Du besser auf pack oder grid setzen

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 25. Juni 2015, 15:13
von Daniel7
@bwbg, vielen Dank für deine Tipps.
Zu deinem Programm hätte ich jedoch noch 3 Fragen:

1) Was ist der Unterschied zwischen "import tkinter as tk" und "from tkinter import *"?
2) Was bewirkt bzw. für was dient die Zeile "super().__init__(parent)"?
3) Wofür dient die Zeile "if __name__ == '__main__': main()"?

Mit freundlichen Grüßen

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 25. Juni 2015, 18:50
von bwbg
Zu 1:
Sternchenimporte holen so ziemlich alles in den Namensraum, "müllen" diesen somit voll.

Zu 2:
Dies ruft vereinfacht gesagt die Initialisierungsmethode (__init__) der Elternklasse auf. Hier solltest Du Dein Wissen über Klassen und Vererbung aufbessern. Dies ist gerade bei GUIs wichtig.

Zu 3:
Das ist das sogenannte main-Idiom. Die Bedingung ist nur wahr, wenn das Python-Programm direkt aufgerufen wird (genau dann ist __name__ gleich "__main__". Ist das der Fall, wird die main-Funktion aufgerufen. Wenn das Modul importiert wird, wird main daher nicht aufgerufen. So kann man Klassen, Funktionen, etc. aus dem Modul nutzen, ohne dass z. B. das Fenster direkt angezeigt würde.

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Samstag 27. Juni 2015, 15:16
von Daniel7
@bwbg, Vielen Dank für diese Erklärung! :)

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 7. Juni 2018, 08:57
von Streifenhase1
Hallo,

versuche mich gerade hier zurechtzufinden, aber komme noch nicht so richtig klar.
Ich habe ein Hauptfenster "main" was auch zu funktionieren scheint und möchte ein zweites "settings" fenster über Button öffnen. zwar öffnet das fenster aber es kommen keinen Buttons etc.


mit dem Bereich komme ich auch noch nicht klar was das bedeutet

Code: Alles auswählen

 def __init__(self, parent, initial_temperature=0):
        super().__init__(parent)
initial_temperatur=0 brauche ich ja nicht wenn ich diesen raus nehme kommt aber als fehler.

Traceback (most recent call last):
File "C:/python36/2.py", line 165, in <module>
main()
File "C:/python36/2.py", line 160, in main
frame = mainframe(fenster, 42)
TypeError: __init__() takes 2 positional arguments but 3 were given



Hier mal der gesamte Code der fenster.

Code: Alles auswählen

#Settings Fenster#
def set_fenster():
        set_fenster = Tk()
        set_fenster.title("Einstellungen")
        set_fenster.geometry("180x500+10+180")
        set_fenster.configure(bg='steelblue1')
        frame = settings(set_fenster, 41)
        frame = settings
        frame.pack()
        set_fenster.mainloop

class settings(tk.Frame):
     def __init__(self, parent, initial_temperature=0):
          super().__init__(parent)
         
          settings_label = Label(self, bg="steelblue1", text="Einstellungen")
          settings_label.place(x = 15, y = 5, width=150, height=40)
          settings_label.config(font=("Arial", 15))
       
          anweisungs_label = Label(self, bg="steelblue1", text="Helligkeit")
          anweisungs_label.place(x = 0, y = 70, width=80, height=40)
        
          bri1_button = Button(self, text="+", background='steelblue1', activebackground='steelblue3', command=cambri1)
          bri1_button.place(x = 80, y = 70, width=40, height=40)
          bri2_button = Button(self, text="-", background='steelblue1', activebackground='steelblue3', command=cambri2)
          bri2_button.place(x = 130, y = 70, width=40, height=40)

class mainframe(tk.Frame):

    def __init__(self, parent):
        super().__init__(parent)
       


        Start_button = Button(self, text=" Starten", background='steelblue1', activebackground='steelblue3',  command=Capture)
        Stop_button = Button(self, text="Stopen", background='steelblue1', command=EXIT)
        Settings_button = Button(self, text="Einstellungen", background='steelblue1', command=set_fenster)
        exit_button = Button(self, text="Beenden", background='steelblue1', command=quit)
        Info_button = Button(self, text="Info", background='steelblue1', command=action_get_info_dialog)
        Start_button.grid(row=0, column=2, pady = 20, padx = 20)    
        Stop_button.grid(row=0, column=4, pady = 0, padx = 20)
        Settings_button.grid(row=0, column=6, pady = 0, padx = 20)
        exit_button.grid(row=0, column=8, pady = 0, padx = 20)
        Info_button.grid(row=0, column=10, pady = 0, padx = 20)
       

    

        
#Hauptfenster
def main():

    fenster = tk.Tk()
    fenster.title("Hauptfenster")
    fenster.geometry("1280x800")
    frame = mainframe(fenster, 42)
    frame.pack()
    fenster.mainloop()
    
if __name__ == '__main__':
    main()



Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 7. Juni 2018, 09:13
von __deets__
Du musst auch die aufrufende Stelle veraendern. Da versuchst du ja immer noch, 42 als Temperatur zu uebergeben. Und die Fehlermeldung sagt dir, welche Zeile den Fehler verursacht: 160, mit der Zeile frame = mainframe(fenster, 42)
.

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 7. Juni 2018, 09:32
von __blackjack__
@Streifenhase1: Es darf übrigens immer nur *ein* `Tk`-Exemplar gleichzeitig existieren. Das ist *das* Hauptfenster. Wenn man zusätzliche Fenster erstellen möchte, nimmt man `Toplevel`. Bei `mainloop()` gilt im Grunde ähnliches. Das sollte nur einmal laufen, es sei denn man weiss genau was man da macht.

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 7. Juni 2018, 13:26
von wuf
Hi Streifenhase1

Was hältst du von folgendem SKript Setup?:

Code: Alles auswählen

import tkinter as tk

APP_TITLE = "Temperature"
APP_XPOS = 10
APP_YPOS = 10
APP_WIDTH = 1280
APP_HEIGHT = 800


class Settings(tk.Toplevel):
    def __init__(self, parent, initial_temperature=0):
        super().__init__(parent)
        
        self.title("Settings")
        
        main_frame = tk.Frame(self)
        main_frame.pack(padx=10, pady=10)
        
        tk.Label(main_frame, text="Einstellungen", font=("Arial", 15)
            ).pack(pady=2)
        
        tk.Label(main_frame, text="Helligkeit").pack(pady=2)

        button_frame = tk.Frame(main_frame)
        button_frame.pack(pady=4)
        
        tk.Button(button_frame, text="+", background='steelblue1',
            activebackground='steelblue3', command=self.cambri1).pack(
                side='left', padx=4)
            
        tk.Button(button_frame, text="-", background='steelblue1',
            activebackground='steelblue3', command=self.cambri2).pack(
                side='left', padx=4)

    def cambri1(self):
        print("cambr1")
        
    def cambri2(self):
        print("cambr2")
        
class MainFrame(tk.Frame):
    
    def __init__(self, haupt_fenster):
        super().__init__(haupt_fenster)
        self.haupt_fenster = haupt_fenster
        self.haupt_fenster.protocol("WM_DELETE_WINDOW", self.close)

        self.build()
        
    def build(self):
        button_frame = tk.Frame(self)
        button_frame.pack(pady=5)
        
        tk.Button(button_frame, text=" Starten", background='steelblue1',
            activebackground='steelblue3',  command=self.capture
            ).pack(side='left', padx=4)
        tk.Button(button_frame, text="Stopen", background='steelblue1', 
            command=self.stop).pack(side='left', padx=4)
        tk.Button(button_frame, text="Einstellungen", background='steelblue1',
            command=self.set_fenster).pack(side='left', padx=4)
        exit_button = tk.Button(button_frame, text="Beenden",
            background='steelblue1', command=self.close).pack(
                side='left', padx=4)
        tk.Button(button_frame, text="Info", background='steelblue1',
            command=self.action_get_info_dialog).pack(side='left', padx=4)

    def capture(self):
        print("Capture")
    def set_fenster(self):
        print("set_fenster")
        self.settings = Settings(self.haupt_fenster)
    def action_get_info_dialog(self):
        print("action_get_info_dialog")
    def stop(self):
        print("Stop")
    def close(self):
        print("Application-Shutdown")
        self.master.destroy()
    
def main():
    haupt_fenster = tk.Tk()
    haupt_fenster.title(APP_TITLE)
    #haupt_fenster.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    haupt_fenster.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    haupt_fenster.option_add("*highlightThickness", 0)
    
    main_frame = MainFrame(haupt_fenster)
    main_frame.pack(fill='both', expand=True, padx=6, pady=6)
    
    haupt_fenster.mainloop()
 
 
if __name__ == '__main__':
    main()
Gruss wuf ;-)

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Donnerstag 7. Juni 2018, 20:20
von Streifenhase1
Ja vielen Dank.

Habe auf deinem Skript aufgebaut. Sicher nicht fehlerfrei aber schon mal was.

Mal sehen ob ich weiter komme.

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Freitag 8. Juni 2018, 08:26
von Streifenhase1
so hab wieder eine Frage...

kann ich in dieser zeile

Code: Alles auswählen

tk.Label(self, textvariable=self.temperature_threshold).pack()
den kleinstmöglichen und den größten wert festlegen? Also das beim betätigen des Buttons der wert dann nicht mehr kleiner oder größer wird?

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Freitag 8. Juni 2018, 08:31
von __deets__
Nein. Eine solche Beschränkung kannst du nur an der Stelle vornehmen, wo du auf eine Aktion des Nutzers reagierst. Du musst als an der Stelle, an der du erhöhst vorher prüfen, ob das ok geht oder nicht. Gleiches mit der Erniedrigung.

Re: Button drücken, Zahl um 1 erhöhen

Verfasst: Freitag 8. Juni 2018, 23:01
von Streifenhase1
Ok Danke.

Dann zum nächsten. Ich habe jetzt z.b. die Temperatur von 42 auf 50 erhöht möchte den Wert aber speichern so das er beim nächsten Start wieder 50 ist.

Das heißt ich muss den Wert in eine .txt Datei speichern und dann wieder auslesen.

Könnt ihr mir das einem Beispiel Skript erklären