Ich hab da mal ne Frage: Wie heißt die Funktion, die durch das Klicken auf einen Button aufgerufen wird, um dann die gekoppelte Funktion aufzurufen?? Gibt es so eine überhaupt? Wenn nein, könnt ihr mir sagen, wie das sonst aufgebaut ist?
Edit: Verständnis der Frage verbessert (-;
Button Command
@Newcomer: Ich verstehe die Frage nicht so ganz. Die Funktion die man als `command` angibt, wird von irgendeiner Funktion oder Methode aus der `Tkinter`-Implementierung aufgerufen. Warum willst Du wissen wie die heisst? Das ist doch egal!?
Naja, ich meine das so: Wenn ich auf ein Button drücke, dem eine eine Methode zugeordnet ist, so wird diese Methode ausgeführt. Aber wie weiß der Button, dass er diese Methode auf knopfdruck ausführen soll, sprich es muss eine Methode in der Button-klasse geben, die 1. nach der dem Button zugeordneten Methode sucht, und 2. diese dann ausführt. Das habe ich gemeint
Hallo Newcommer
Meinst du so etwas?:
Gruß wuf
Meinst du so etwas?:
Code: Alles auswählen
import Tkinter as tk
def button_func():
print "Du hast mich gerufen?"
app_win = tk.Tk()
button = tk.Button(app_win, text='Button', command=button_func)
button.pack()
app_win.mainloop()
Take it easy Mates!
Ja indirekt, das kannte ich schon. Ich meinte innerhalb der Button-Class muss irgendeine methode das event "klick" prüfen. Und von der will ich den Namen. Ich benötige diesen Methodennamen, da ich die Methode selber etwas verändern will
Perfekt, danke hab nur in der Buttonklasse nachgeschaut. Hab gar nicht drangedacht in misc auch zu schauen. Dort hab ich schließlich gefunden was ich wollte ( Funktion: getint_event)
Edit: Nein ich ihn nicht umschreiben, möchte nur einen MegaButton erstellen, der alle Buttons in sich vereint (-:
Edit: Nein ich ihn nicht umschreiben, möchte nur einen MegaButton erstellen, der alle Buttons in sich vereint (-:
Ich verstehe es immer noch nicht?! Was nutzt dir diese Information "getint_event" versucht nur einen String in einen Integer-Wert umzuwandeln. Das ist deshalb nötig weil Tkinter ein Wrapper ist und mit dem Tcl-Interpreter nur in Form von Strings kommunizieren kann. Darum bekommt "_substitute" die gesamten Eventdaten aus einer aufbereiteten Stringkette, diese Daten werden dann der Python-Klasse "Tkinter.Event" zugeordnet und der Datentyp gleich richtig gesetzt. Also wie hilft "getint_event" dir da ?
Falls du es nicht Wissen solltest Tk hat ein Event-System in dem per <bind> gearbeitet wird, so ist auch der Button implementiert. Siehe z.B. den Studbutton in Tkinter.py. Wenn du den normalen Button sehen willst, musst du dir den Tcl-Skript für den Button ansehen. Hier ein kleiner Ausschnitt
Allerdings verstehe ich auch noch nicht was ein MegaButton sein soll und was dieser können müsste, aber lass dir eins gesagt sein:
Falls du es nicht Wissen solltest Tk hat ein Event-System in dem per <bind> gearbeitet wird, so ist auch der Button implementiert. Siehe z.B. den Studbutton in Tkinter.py. Wenn du den normalen Button sehen willst, musst du dir den Tcl-Skript für den Button ansehen. Hier ein kleiner Ausschnitt
Code: Alles auswählen
bind Button <Leave> {
tk::ButtonLeave %W
}
bind Button <1> {
tk::ButtonDown %W
}
bind Button <ButtonRelease-1> {
tk::ButtonUp %W
}
bind Checkbutton <FocusIn> {}
bind Checkbutton <Leave> {
tk::ButtonLeave %W
}
bind Radiobutton <FocusIn> {}
bind Radiobutton <Leave> {
tk::ButtonLeave %W
}
The Zen of Python hat geschrieben:Explicit is better than implicit.
Simple is better than complex.
Na ja pass auf: Ich denke du verstehst mich immer noch nicht, aber meine Frage hat sich schon erledigt, weil ich diese Funktion (und ein paar andere) gefunden habe. Und ein MegaButton soll eine Klasse sein, die alle anderen Button Klassen in sich vereint. Ich dachte da an sowas:
Code: Alles auswählen
Megabutton(main,type_button...)
@Newcomer: Das man Dich nicht versteht, könnte daran liegen, dass Du es nicht wirklich erklärst. Was ist das für eine Vereinigung? Die Eigenschaften von verschiedenen Button-Typen? Und was ist wenn die sich widersprechen? Gibt es ausser `Tkinter.Button` denn überhaupt noch andere Button-Klassen? Oder meinst Du Exemplare und nicht Klassen? Und was ist *davon* dann eine Vereinigung? Wenn man den Megabutton drückt, werden alle anderen auch gedrückt? Also zum Beispiel ”Ok” und ”Cancel” *gleichzeitig*!?
Und warum musst Du dafür in den Innereien von `Tkinter` rumwühlen? Wenn Du einen neuen Button-Typ haben möchtest, dann erweitere einfach den vorhandenen durch eine Unterklasse.
Und warum musst Du dafür in den Innereien von `Tkinter` rumwühlen? Wenn Du einen neuen Button-Typ haben möchtest, dann erweitere einfach den vorhandenen durch eine Unterklasse.
@Newcomer
Habe ich das jetzt richtig verstanden? Du möchstest statt: bspw. folgendes schreiben:
oder wie ist das zu verstehen?
Das kann man z.B. auch so machen:
bzw. das ganze noch schick in einer Funktion verpacken, aber wozu musst du für diese Implementierung an die Tk[inter] interne herran?
Habe ich das jetzt richtig verstanden? Du möchstest statt:
Code: Alles auswählen
bt = Button(master)
cbt = CheckButton(master)
rbt = RadioButton(master)
sbt = StudButton(master)
#...
Code: Alles auswählen
mb = MegaButton(master, "CheckButton")
Das kann man z.B. auch so machen:
Code: Alles auswählen
import Tkinter
#...
button = getattr(Tkinter, "CheckButton")
mb = button(master)
bzw. das ganze noch schick in einer Funktion verpacken, aber wozu musst du für diese Implementierung an die Tk[inter] interne herran?
Ja du hast es verstanden (sorry wegen meinen schlechten Formulierungen)!!! Die Methode kannte ich noch nicht mit getattr. Ich zog Tkinter deshalb heran, da ich der Option "command" einen Parameter übergeben wollte. Das hat nicht so ganz geklappt. Ich wollte wissen, wie die Funktion die commadn übergeben wird, aufgerufen wird. Da ich dergleichen nicht gefunden habe, habe ich das jetzt ander versucht:
Code: Alles auswählen
from tkinter import *
class MegaVar(StringVar):
def __init__(self):
StringVar.__init__(self)
self.container =[]
def seed(self,button):
if len(self.container) >=1:
self.container = []
self.container.append(button)
def seed_get(self):
return self.container
class MegaButton(Button):
def __init__(self,main,zähler,figur_ja,bg=None,width=10,height=10,command=None,var=None):
Button.__init__(self,main,bg=bg,width=width,height=height,command=None)
self.index=False
self.zähler=zähler
self.figur_ja=figur_ja
self.var=var
self.bind("<ButtonPress>",self.callback_start)
self.bind("<ButtonRelease>",self.callback_end)
self.command=command
def get_counter(self):
return self.zähler
def get_stand(self):
return self.figur_ja
def callback_end(self,*dummy):
self.command()
def callback_start(self, *dummy):
self.var.seed(self)
# Test funktion
def con():
global c
k=c.seed_get()
try:
k[0].config(bg="blue")
except IndexError:
pass
# Test
a=Tk()
c=MegaVar()
o=list()
for i in range(50):
b=MegaButton(a,1,False,command=con,var=c)
o.append(b)
b.pack()
a.mainloop()
@Newcomer: Das sieht alles sehr eigenartig aus. Beide Klassen scheinen die Oberklasse nicht wirklich zu benötigen. Von `MegaVar` wird anscheinend überhaupt nicht verwendet, dass es ein `StringVar`-Objekt ist und bei dem `MegaButton` wird vom `Button` das `command` nicht verwendet und die Reaktionen auf die Maus werden überschrieben so dass man sich fragen muss, warum das überhaupt von einem `Button` erbt.
Was soll `MegaVar.container`? Eine Liste die maximal ein Element enthält, erscheint mir sehr merkwürdig und so wie es da verwendet wird, auch umständlich. Triviale Getter-Methoden sind ”unpythonisch”. `get_seed()` und `get_counter()` kann man einfach weglassen beziehungsweise bei `seed` durch ein `property()` ersetzen. Falls diese komische Liste mit Länge ≤ 1 wirklich sein muss.
``global`` sollte man nicht verwenden — ist hier auch völlig unnötig. Allerdings sollte man in Funktionen auch nicht auf Werte zugreifen die auf Modulebene liegen aber keine Konstanten sind.
Ich sehe bei dem Beispiel nicht wirklich, dass man dafür einen eigenen `Button`-Typ benötigt. Oder übersehe ich etwas? Was genau soll das denn darstellen?
Der Sternchen-Import ist auch unschön. Bei `tkinter` ist ein Import, der den Namen auf `tk` kürzt üblich. Die Leerzeilen sind ein wenig üppig, dafür könnten mehr Leerzeichen verwendet werden. Die Funktionssignatur von `MegaButton.__init__()` ist zum Beispiel schwer lesbar so zusammen gequetscht.
So grundsätzlich vom Effekt her sollte das hier doch zumindest etwas sehr ähnliches machen, oder?
Was soll `MegaVar.container`? Eine Liste die maximal ein Element enthält, erscheint mir sehr merkwürdig und so wie es da verwendet wird, auch umständlich. Triviale Getter-Methoden sind ”unpythonisch”. `get_seed()` und `get_counter()` kann man einfach weglassen beziehungsweise bei `seed` durch ein `property()` ersetzen. Falls diese komische Liste mit Länge ≤ 1 wirklich sein muss.
``global`` sollte man nicht verwenden — ist hier auch völlig unnötig. Allerdings sollte man in Funktionen auch nicht auf Werte zugreifen die auf Modulebene liegen aber keine Konstanten sind.
Ich sehe bei dem Beispiel nicht wirklich, dass man dafür einen eigenen `Button`-Typ benötigt. Oder übersehe ich etwas? Was genau soll das denn darstellen?
Der Sternchen-Import ist auch unschön. Bei `tkinter` ist ein Import, der den Namen auf `tk` kürzt üblich. Die Leerzeilen sind ein wenig üppig, dafür könnten mehr Leerzeichen verwendet werden. Die Funktionssignatur von `MegaButton.__init__()` ist zum Beispiel schwer lesbar so zusammen gequetscht.
So grundsätzlich vom Effekt her sollte das hier doch zumindest etwas sehr ähnliches machen, oder?
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tkinter as tk
from functools import partial
def main():
root = tk.Tk()
last_button = None
def command(button):
nonlocal last_button
last_button = button
button['bg'] = 'blue'
for i in range(10):
button = tk.Button(root, width=5, height=5)
button['command'] = partial(command, button)
button.pack()
root.mainloop()
if __name__ == '__main__':
main()
Ja stimmt, sowas sollte mein skript darstellen. Es ist aber noch ziemlich unfertig und ich wollte die StirngVar (ich denke ich hätte lieber die Elternklasse vererben sollen) noch gebrauchen. Außerdem wollte ich die Klassen noch erweitern und ein paar andere Elemente hinzubauen. Im übrigen weiß ich, dass mien skript nicht das beste ist (-: Ich kenn halt nicht so viele möglichkeiten, dann benutze ich die, die mir als erste durch den kopf schwirren