Seite 1 von 1
relief="sunken" immer nur bei einem Button
Verfasst: Sonntag 16. Juli 2006, 13:59
von dh233
Wieder einmal steh ich vor einem Problemchen:
Ich hab mehrere Buttons erstellt, es soll aber immer nur der Button, der als letztet gedrückt wurde relief="sunken" aktiviert haben, damit man weiß, in welchem Menü man sich gerade befindet.
Wie kann ich bei allen Buttons die relief="sunken" deaktivieren??
Danke, lG
dh233
Verfasst: Sonntag 16. Juli 2006, 15:23
von BlackJack
Das Gegenteil von `Tkinter.SUNKEN` ist `Tkinter.RAISED`.
Verfasst: Sonntag 16. Juli 2006, 15:33
von dh233
Ok, ich hab jetzt einfach eine Methode geschrieben, die alle Buttons zuerst auf relief="raised" setzt.
Das einzige, was mir jetzt noch fehlt ist, wie man den Namen des aufrufenden Objekts verwendet, denn da ergibt sich ein Problem bei folgender Methode:
Code: Alles auswählen
def clearButtons():
self.BBanners.configure(relief="raised")
self.BMetasploit.configure(relief="raised")
self.BNessus.configure(relief="raised")
self.BOSfinger.configure(relief="raised")
self.BPorts.configure(relief="raised")
self.BReports.configure(relief="raised")
self.DNS.configure(relief="raised")
def setRelief():
clearButtons()
self.BPorts.configure(relief="sunken")
Beim Aufruf von
self.BPorts=Button(self.nav, text="Ports", width=15, command=setRelief
gibt es einen Fehler. Das hat sicher was damit zu tun, dass die ganzen Aufrufe im Konstruktor __init__ stehen, oder??
Verfasst: Sonntag 16. Juli 2006, 15:57
von dh233
Ich hab jetzt mal für jeden Button seine eigene Methode definiert. Das Problem liegt anscheinend daran, dem Parameter "command" beim Aufruf keinen Parameter mitgeben kann:
Code: Alles auswählen
self.BReports=Button(self.nav, text="Reports", width=15, command=setBReportsRelief)
Ich müsste allerdings "command=setBReportsRelief" mit einem Parameter aufrufen. Z.B.:
"command=setBReportsRelief
(BReports)"
Verfasst: Sonntag 16. Juli 2006, 16:55
von BlackJack
dh233 hat geschrieben:Code: Alles auswählen
def clearButtons():
self.BBanners.configure(relief="raised")
self.BMetasploit.configure(relief="raised")
self.BNessus.configure(relief="raised")
self.BOSfinger.configure(relief="raised")
self.BPorts.configure(relief="raised")
self.BReports.configure(relief="raised")
self.DNS.configure(relief="raised")
Das sieht nach einer Methode aus, dann fehlt der Parameter `self`. Man kann das auch ohne soviel copy'n'paste schreiben:
Code: Alles auswählen
def clearButtons(self):
for button_name in ('BBanners', 'BMetasploit', 'BNessus', 'BOSfinger',
'BPorts', 'BReports', 'DNS'):
getattr(self, button_name).configure(relief=Tkinter.RAISED)
Code: Alles auswählen
def setRelief():
clearButtons()
self.BPorts.configure(relief="sunken")
Auch hier fehlt wieder der `self` Parameter. Und auch vor `clearButtons()` muss eins, da es sich um eine Methode handelt und nicht um eine Funktion im Modul.
Beim Aufruf von
self.BPorts=Button(self.nav, text="Ports", width=15, command=setRelief
gibt es einen Fehler. Das hat sicher was damit zu tun, dass die ganzen Aufrufe im Konstruktor __init__ stehen, oder??
Sozusagen. Es gibt keine Funktion `setRelief` sondern eine Methode auf dem Objekt das gerade initialisiert wird. Also auch hier fehlt wieder ein `self`.
Verfasst: Sonntag 16. Juli 2006, 17:02
von BlackJack
dh233 hat geschrieben:Ich hab jetzt mal für jeden Button seine eigene Methode definiert. Das Problem liegt anscheinend daran, dem Parameter "command" beim Aufruf keinen Parameter mitgeben kann:
Code: Alles auswählen
self.BReports=Button(self.nav, text="Reports", width=15, command=setBReportsRelief)
Ich müsste allerdings "command=setBReportsRelief" mit einem Parameter aufrufen. Z.B.:
"command=setBReportsRelief
(BReports)"
Letzteres funktioniert natürlich nicht, weil Du damit die Funktion
aufrufst und deren Rückgabewert dann als Kommando für den Button benutzt wird. Also kann man eine Funktion schreiben, die eine Funktion zurück gibt, die das gewünschte tut:
Code: Alles auswählen
def make_set_relief(button):
def set_relief():
button.configure(relief=Tkinter.SUNKEN)
return set_relief
Verfasst: Sonntag 16. Juli 2006, 22:28
von HWK
Das dürfte doch mit einer lambda-Funktion einfacher gehen, z.B.:
Code: Alles auswählen
def setRelief(self, button):
self.clearButtons()
button.configure(relief="sunken")
self.BPorts=Button(self.nav, text="Ports", width=15,
command=lambda arg=self.BPorts: self.setRelief(arg))
Verfasst: Dienstag 18. Juli 2006, 18:29
von dh233
Alles klar, Danke!
Werds mal ausprobieren.
Verfasst: Dienstag 18. Juli 2006, 20:06
von HWK
Ich habe leider übersehen, dass self.BPorts in der Buttonerstellung nicht als Argument übergeben werden kann, weil es noch nicht bekannt ist. Ich habe deshalb die Buttonerstellung in zwei Schritte aufgeteilt. Vorsichtshalber habe ich es in einem Beispielscript einmal ausprobiert. Es funktioniert:
Code: Alles auswählen
from Tkinter import *
class MyClass:
def __init__(self, master):
self.button_list = ('Banners', 'Metasploit', 'Nessus', 'Osfinger',
'Ports', 'Reports', 'DNS')
for name in self.button_list:
bname = 'B%s' % name
setattr(self, bname, Button(master, text=name, width=15))
getattr(self, bname).config(command=lambda arg=getattr(self, bname):
self.set_relief(arg))
getattr(self, bname).pack()
def set_relief(self, button):
for name in self.button_list:
getattr(self, 'B%s' % name).config(relief="raised")
button.config(relief="sunken")
root=Tk()
MyClass(root)
root.mainloop()
MfG
HWK
Verfasst: Mittwoch 19. Juli 2006, 11:05
von dh233
Danke HWK, das funkt einwandfrei!
Hab noch was anderes gefunden: Man könnte das Ganze auch mit Radiobuttons machen und "indicatoron=0" verwenden.
Code: Alles auswählen
from Tkinter import *
master = Tk()
v = IntVar()
Radiobutton(master, text="One", variable=v, value=1, indicatoron=0).pack(anchor=W)
Radiobutton(master, text="Two", variable=v, value=2, indicatoron=0).pack(anchor=W)
mainloop()
Das funktioniert mal an einem einfachen Beispiel, aber ob es später damit Probleme gibt und Buttons besser wären, kann ich noch nicht sagen.
lG
dh233
Verfasst: Mittwoch 19. Juli 2006, 14:14
von HWK
Das sieht gut aus und ist ja noch einfacher!