Seite 1 von 1

Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 12:09
von Windy
Hallo,

hab da mal eine Abfängerfrage.

Kann man innerhalb einer Funktion ermitteln welcher Button die Funktion aufgerufen hat?
Ich möchte mit mehreren Buttons die gleiche Funktion aufrufen und innerhalb der Funktion den Button ermitteln.

Vielen Dank im Voraus
Windy

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 12:50
von BlackJack
@Windy: Willst Du wirklich den Button ermitteln oder einen anderen Wert der damit zusammenhängt? Egal was, Du solltest es nicht in der Funktion/Methode ermitteln sondern als Argument übergeben lassen. Schau Dir mal `functools.partial()` an.

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 13:55
von Windy

Code: Alles auswählen

from tkinter import *
from tkinter import ttk
import functools

def ereignis(nr):
    print(nr)

fenster = Tk()
a = Button(fenster, text='a', command=functools.partial(ereignis, '1'))
a.place(x=10, y= 10)

b = Button(fenster, text='b', command=functools.partial(ereignis, '2'))
b.place(x=50, y= 10)

fenster.geometry("2000x1000")
fenster.mainloop()
Sieht ungewöhnlich aus, funktioniert aber.

Dake für den Tipp

Gruß
Windy

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 14:45
von BlackJack
@Windy: Den Sternchen-Import und `place()` solltest Du loswerden. Mit Sternchen-Importen wird es schnell unübersichtlich so Namen herkommen und es besteht auch die Gefahr von Namenskollisionen. `place()` macht nur in sehr wenigen Fällen Sinn, und ansonsten im besten Fall nur Arbeit und im schlechten Fall unbenutzbare GUIs auf Systemen mit anderen Einstellungen.

Sind die Klammern für den Aufruf bei `mainloop()` beim kopieren verloren gegangen?

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 15:07
von Windy
Hi,

dass mit dem mainloop() ist mir bis jetzt nie aufgefallen, da es keinen Fehler gab.

Das mit dem Sternchen ist bekannt. Versuche mich gerade etwas in Tkinter einzuarbeiten
und das sind Testscripte, die ich gerade schreibe.

Habe mir bereits die drei Möglichkeiten der Plazierung angesehen und mir ist persönlich
einfach die direkte Plazierung am sympathischsten.

Danke für die Hilfe
Gruß
Windy

PS. kann es sein, dass wenn Du als Admin in meinem Beitrag etwas änderst, dass ich dann keinen zugriff mehr auf eben diesen habe?

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 15:41
von BlackJack
@Windy: Ich glaube nicht das eine Veränderung als Admin den Beitrag sperrt — nach 5 Minuten wird der automatisch gesperrt. Wir hatten mal jemanden der meinte Diskussionen nachträglich verändern zu müssen und Spammer nerven auch manchmal in dem sie erst harmlose Beiträge erstellen und die dann wenn keiner mehr hinschaut nach einiger Zeit den Text mit Werbelinks ersetzen.

Wenn Dir das mit der `mainloop()` noch nie aufgefallen ist, hast Du so ein Programm wohl noch nie ausserhalb einer IDE aufgerufen die das irgendwie im Hintergrund für Dich löst. :-)

Die direkte Platzierung funktioniert nicht wirklich weil die Leute sehr unterschiedliche Bildschirmgrössen und -auflösungen und dementsprechend auch Pixelgrössen und Schriftgrössen und so weiter haben. Das was bei Dir richtig aussieht, kann bei jemand anderen so ungünstig ineinander Verschoben angezeigt werden, das die GUI nicht mehr richtig bedienbar ist. Und es ist auch massiv arbeitsaufwändig bei einer GUI nachträglich etwas einzufügen, zu entfernen, oder in der Grösse zu verändern oder zu verschieben, wenn man dann von Hand alles mögliche andere was dadurch dann auch verschoben werden muss, anpassen muss. Und zu guter letzt möchte man vielleicht auch mal programmatisch Inhalte ändern die Grössenänderungen nach sich ziehen. Zum Beispiel ein Programm mehrsprachig machen, wodurch sich dann die länge von Texten und damit auch die Grösse von `Button`\s, `Label`\s, usw. ändern.

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Montag 17. Juli 2017, 18:20
von Windy
Hi,

wie gesagt ich teste bzw. experimentier etwas mit tkinter herum. Da kommt noch kein PRG zum weitergeben raus. Deswegen ist mir das mit den Klammern auch nicht aufgefallen. Darf ich dich nochmals bemühen, kannst Du sie nachträglich ins Skript reinpacken(die fehlenden Klammern). Ich kann es ja nicht mehr.

Danke nochmals

Viele Grüße
Windy

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 14:24
von Alfons Mittelmeyer
Windy hat geschrieben: a = Button(fenster, text='a', command=functools.partial(ereignis, '1'))
a.place(x=10, y= 10)
Ja warum machst Du es nicht so?

Code: Alles auswählen

a = Button(fenster, text='a')
a['command'] = functools.partial(ereignis, '1',a)
a.place(x=10, y= 10)

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 14:56
von kbr
Alfons Mittelmeyer hat geschrieben:Ja warum machst Du es nicht so?

Code: Alles auswählen

a = Button(fenster, text='a')
a['command'] = functools.partial(ereignis, '1',a)
a.place(x=10, y= 10)
Ohne dies jetzt getestet zu haben: Es sieht weder einfacher noch intuitiv aus. Und vor allem: wo ist das dokumentiert?

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:00
von Alfons Mittelmeyer
kbr hat geschrieben:
Alfons Mittelmeyer hat geschrieben:Ja warum machst Du es nicht so?

Code: Alles auswählen

a = Button(fenster, text='a')
a['command'] = functools.partial(ereignis, '1',a)
a.place(x=10, y= 10)
Ohne dies jetzt getestet zu haben: Es sieht weder einfacher noch intuitiv aus. Und vor allem: wo ist das dokumentiert?
Was soll wo dokumentiert sein? Es is klar, dass man zuerst den Button haben muss, also 'a =', bevor man den Button als Parameter übergeben kann. Oder ist Dir das nicht klar?

Und es ist überall dokumentiert, das man config Parameter auf drei Arten übergeben kann, nämlich beim Anlegen des Widgets:

a = Button(fenster, text='a', command=some_command)

Nachher durch config:
a = Button(fenster)
a.config(text='a', command=some_command)

Nachher so:
a = Button(fenster)
a['text' ] = 'a'
a['command'] = some_command

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:02
von BlackJack
@kbr: Das ist der Weg den man nehmen muss wenn man das `Button`-Objekt selbst beim Erstellen des Wertes für die Option `command` braucht. Denn beim erstellen des `Button`-Objekts gibt es das ja noch nicht. Ich sehe da jetzt nichts undokumentiertes‽

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:12
von Alfons Mittelmeyer
BlackJack hat geschrieben:@kbr: Das ist der Weg den man nehmen muss wenn man das `Button`-Objekt selbst beim Erstellen des Wertes für die Option `command` braucht. Denn beim erstellen des `Button`-Objekts gibt es das ja noch nicht. Ich sehe da jetzt nichts undokumentiertes‽
Natürlich sind die Arten der Übergabe von config Parametern dokumentiert. Die Frage ist, ist auch dokumentiert, welche Parameter man beim Anlegen des Widgets übergeben kann und welche man erst hinterher dorch config übergeben muss. Ich hatte nämlich gemerkt, dass es Parameter gibt, welche beim Anlegen des Widgets einen Fehler auslösen, aber hinterher bei config funktionieren, Genauso kann es aber bei manchen Parametern auch umgekehrt sein. Leider erinnere ich mich jetzt gerade nicht mehr, welche Parameter das waren.

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:31
von kbr
BlackJack hat geschrieben:Das ist der Weg den man nehmen muss wenn man das `Button`-Objekt selbst beim Erstellen des Wertes für die Option `command` braucht.
Schon klar. Mich hatte auf die Schnelle das a['command'] irritiert. Aber ja, das geht auch so – das hatte ich wohl vergessen. Ein schneller Blick in tkinter sources zeigte mir jedoch nicht, an welcher Stelle im Code dafür gesorgt wird, dass ein Widget sich wie ein Dictionary verhält. Bei dem tkinter-Code lässt sich aber auch schnell was übersehen.

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:42
von Alfons Mittelmeyer
kbr hat geschrieben:Ein schneller Blick in tkinter sources zeigte mir jedoch nicht, an welcher Stelle im Code dafür gesorgt wird, dass ein Widget sich wie ein Dictionary verhält. Bei dem tkinter-Code lässt sich aber auch schnell was übersehen.
Ja statt Sourcen, sollte man sich wohl besser zuerst einmal eine Einführung anschauen, etwa: effbot.org/tkinterbook/tkinter-widget-configuration.htm

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:54
von BlackJack
@kbr: Das steckt in der Klasse `Misc`. Von der erbt `BaseWidget` und von der wiederum `Widget`. Und der Quelltext von dem Modul ist streckenweise nicht schön. :-)

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 15:59
von kbr
BlackJack hat geschrieben:@kbr: Das steckt in der Klasse `Misc`. Von der erbt `BaseWidget` und von der wiederum `Widget`. Und der Quelltext von dem Modul ist streckenweise nicht schön. :-)
Ja, bis 'Misc' war ich gekommen, habe es dort aber nicht gesehen. Und den Quelltext fand ich auch nicht sehr prickelnd ... :)

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Samstag 29. Juli 2017, 17:24
von BlackJack
@kbr: Ich hatte mir mit ``??`` in IPython den Quelltext vom Modul anzeigen lassen und da dann nach ``__setitem__`` gesucht. Unter Linux wird ``less`` zum Anzeigen verwendet und das hat ja eine Suchfunktion. Der erste Treffer war dann auch schon der richtige. Von dort hatte ich rückwärts nach ``^class`` gesucht. :-)

Re: Innerhalb einer Funktion auslösenden Button ermitteln

Verfasst: Sonntag 30. Juli 2017, 11:13
von kbr
@BlackJack: IPython ist schon recht praktisch für so was. Zumeist nutze ich es mit Jupyter. Im konkreten Fall habe ich meinen Editor verwendet, der für Editoren über eine gute Suche verfügt. Nach __setitem__ hatte ich gestern nicht gesucht. Dies habe jetzt nachgeholt — und voila, da ist es :)