Button Hintergrundfarbe

Fragen zu Tkinter.
LIFE-CUBES
User
Beiträge: 14
Registriert: Freitag 17. Februar 2012, 17:38

1.: global brauch ich, sonst wird die (großgeschriebene) variable nicht gesetzt und ich kann sie in unterfunktionen nicht mehr benutzen
2.: ob groß oder klein --> egal!? weil ich sie ja definiere
3.:es hilft mir bei meinem eigentlichen problem nicht!

es gibt ja keine fehlermeldungen, probierts es doch mal aus! ich will einfach nur die config bei einem button ändern!
das kleine programm von oben funktioniert eigentlich, nur die automatisation fehlt mir!!!


mfg
LIFE-CUBES
User
Beiträge: 14
Registriert: Freitag 17. Februar 2012, 17:38

besser so?

Code: Alles auswählen

from Tkinter import *
from sys import stdout, exit
VARIABLE='white'
def destroy():
    global VARIABLE
    VARIABLE='green' #Will noch eine Variable setzen
    frame.destroy()
    #und die unterfunktion wieder ausführen ev. mit
def unterfunktion():
    frame=Toplevel()
    button = Button(frame, text='Schließen!', command=destroy) #im button.config befindet sich eben die Variable
    button.config(bg=VARIABLE)
    button.pack( )
main=Tk()
widget = Button(main, text='Unterfunktion', command=unterfunktion )
widget.pack( )
main.mainloop( )
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi LIFE-CUBES
Habe dein vorheriges Skript einmal versucht abzuändern so wie ich die Funktion aus dem Skript interpretiere.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import Tkinter as tk

def destroy():
    app_win.variable = 'green'
    app_win.toplevel_win.destroy()

def unterfunktion():
    app_win.toplevel_win = tk.Toplevel()
    tk.Button(app_win.toplevel_win, text='Schließen!', bg=app_win.variable,
        command=destroy).pack( )
 
app_win = tk.Tk()

app_win.variable = 'white'

app_win.button_01 = tk.Button(app_win, text='Unterfunktion', command=unterfunktion )
app_win.button_01.pack()

app_win.mainloop( )
Dein letztes Post werde ich gleich noch anschauen.

Gruß wuf :wink:
Take it easy Mates!
LIFE-CUBES
User
Beiträge: 14
Registriert: Freitag 17. Februar 2012, 17:38

Ich könnt dich küssen! Das ist es!!! :)
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

OK LIFE-CUBES

Dein letztes Skript ist schon bedeutend besser! Ich habe es noch so abgeändert, dass es keine Exceptions mehr wirft. Die Funktion 'destroy' konnte die Toplevel-Instanz 'frame' noch nicht sehen. Machte sie deshalb global. Global ist obwohl die Sprache Python sie in ihrem Wort-Vokabular hat verpöhnt. Aber für ein kleines Versuchsskript ist seine Anwendung keine Schande. Bei grösseren Programmen könnte es aber zu schwer auffindbaren Fehlern führen. Beim meinem Skript habe ich die global benötigten namen an die Instanz 'app_win' gebunden. Dies könnte aber auch zu Problemen führen da Attribute in der 'app_win'-Instanz, welche die gleiche Namen besitzen überschrieben werden könnten. Werde dein Skript noch näher anschauen um das Geisterwort 'global' zu eliminieren.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from Tkinter import *
from sys import stdout, exit
VARIABLE='white'

def destroy():
    global VARIABLE, frame
    VARIABLE='green' #Will noch eine Variable setzen
    frame.destroy()
    #und die unterfunktion wieder ausführen ev. mit
    
def unterfunktion():
    global frame
    frame=Toplevel()
    button = Button(frame, text='Schließen!', command=destroy) #im button.config befindet sich eben die Variable
    button.config(bg=VARIABLE)
    button.pack( )
    
main=Tk()
widget = Button(main, text='Unterfunktion', command=unterfunktion )
widget.pack( )
main.mainloop( )
Gruß wuf :wink:
Take it easy Mates!
LIFE-CUBES
User
Beiträge: 14
Registriert: Freitag 17. Februar 2012, 17:38

Danke vielmals! Hast mir wirklich weiterhelfen können!
MfG
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi LIFE-CUBES

Hier noch meine Variante das 'global' mit einer Hilfsklasse 'App' zu eliminieren. Man kann dann gobal verwendete Namen als Attribute an die Instanz 'app' der Klasse 'App' binden. Da haben eventuell unsere Forum-Kollegen noch bessere Lösungen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from Tkinter import *
from sys import stdout, exit

def destroy(frame):
    app.variable='green'
    frame.destroy()
    
def unterfunktion():
    frame=Toplevel()
    Button(frame, text='Schließen!', bg=app.variable,
        command=lambda:destroy(frame)).pack()


class App(object):
    def __init__(self):
        pass
    

main=Tk()

app = App()
app.variable = 'white'

Button(main, text='Unterfunktion', command=lambda:unterfunktion()).pack()

main.mainloop()
Gruß wuf :wink:
Take it easy Mates!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Kleiner, etwas später Hinweis, weil ich das grad sehe:

Code: Alles auswählen

Button(main, text='Unterfunktion', command=lambda:unterfunktion()).pack()
würde man besser als

Code: Alles auswählen

Button(main, text='Unterfunktion', command=unterfunktion).pack()
schreiben, denn es ist sinnlos einen Funktionsaufruf in eine Funktion zu packen. Merkregel: wenn man ``lambda`` im Code stehen hat, gibt es meist eine bessere Möglichkeit das Problem zu lösen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Leonidas

Hast du richtig festgestellt. Danke für den Hinweis.
Leonidas hat geschrieben:Merkregel: wenn man ``lambda`` im Code stehen hat, gibt es meist eine bessere Möglichkeit das Problem zu lösen.
Meinst du damit etwa:

Code: Alles auswählen

from functools import partial
Gruß wuf :wink:
Take it easy Mates!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

wuf hat geschrieben:Meinst du damit etwa:

Code: Alles auswählen

from functools import partial
Oft, ja. Manchmal aber auch ``operator.attrgetter`` (statt ``lambda foo: foo.baz``) und ``operator.itemgetter`` (statt ``lambda foo: foo[42]``). Ich persönlich find das klarer, aber da kann man sich streiten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Leonidas hat geschrieben:Oft, ja. Manchmal aber auch ``operator.attrgetter`` (statt ``lambda: foo['baz']``) und ``operator.itemgetter`` (statt ``lambda: foo[42]``)
@Leonidas: Die Begriffe:

Code: Alles auswählen

operator.attrgetter
und

Code: Alles auswählen

`operator.itemgetter
sind neu für mich obwohl ich diesem Forum schon länger Zeit beiwohne. Muss gestehen bis jetzt habe ich "lambda" hauptsächlich nur bei Tkinter-Anwendungen verwendet. Ersetzte es aber in jüngster Zeit mehr durch partial. Ich habe betreffs den für mich neuen Begriffen schon herumgegoogelt und auch im Forum gesucht. Aber bei mir fängt die Lampe noch nicht an zu brennen. Möchte dich fragen wie du die "operator.attrgetter" bzw. "operator.itemgetter" in der folgenden Tkinter-Zeile anwendest:

Code: Alles auswählen

Button(frame, text='Schließen!', bg=app.variable,
        command=lambda:destroy(frame)).pack()
Mit partial würde ich es wie folgt lösen:

Code: Alles auswählen

Button(frame, text='Schließen!', bg=app.variable,
        command=partial(destroy, frame)).pack()
Aber mit den neuen Begriffen schnalle ich es noch nicht.

Danke dir im Voraus.

Gruß wuf :wink:
Take it easy Mates!
deets

@wuf: das loest man damit auch nicht. attrgetter und itemgetter erzeugen kleine Funktionen, die eben genau das machen, was ihre namen besagen: ein attribut oder item zurueckzulieferen, wenn man sie mit einem objekt aufruft. in etwa so:

Code: Alles auswählen

def itemgetter(index):
     def f(value):
           return value[index]
     return f

foo = itemgetter(0) # statt lambda d: d[0]
print foo({0 : "hallo"}) 
analog auch attrgetter. damit ist man jetzt nicht unbedingt viel kompakter als mit lambdas. aber es ist ein bisschen wie mit map/filter/reduce oder list-comprehensions: die machen nicht viel mehr als eine normal schleife auch. aber wenn ich die sehe, weiss ich genau, was passiert - ich muss also nicht den ausdruck weiter zerlegen und verstehen, sondern kann ihn viel einfacher ueberlesen.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi deets

Super! Besten Dank für deine erleuchtende Erklärung. Der Groschen ist jetzt gefallen.

Gruß wuf :wink:
Take it easy Mates!
Antworten