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
relief="sunken" immer nur bei einem Button
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:
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??
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")
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??
Code: Alles auswählen
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:
Ich müsste allerdings "command=setBReportsRelief" mit einem Parameter aufrufen. Z.B.:
"command=setBReportsRelief(BReports)"
Code: Alles auswählen
self.BReports=Button(self.nav, text="Reports", width=15, command=setBReportsRelief)
"command=setBReportsRelief(BReports)"
Das sieht nach einer Methode aus, dann fehlt der Parameter `self`. Man kann das auch ohne soviel copy'n'paste schreiben: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")
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)
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.Code: Alles auswählen
def setRelief(): clearButtons() self.BPorts.configure(relief="sunken")
Sozusagen. Es gibt keine Funktion `setRelief` sondern eine Methode auf dem Objekt das gerade initialisiert wird. Also auch hier fehlt wieder ein `self`.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??
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: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:
Ich müsste allerdings "command=setBReportsRelief" mit einem Parameter aufrufen. Z.B.:Code: Alles auswählen
self.BReports=Button(self.nav, text="Reports", width=15, command=setBReportsRelief)
"command=setBReportsRelief(BReports)"
Code: Alles auswählen
def make_set_relief(button):
def set_relief():
button.configure(relief=Tkinter.SUNKEN)
return set_relief
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))
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:
MfG
HWK
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()
HWK
Danke HWK, das funkt einwandfrei!
Hab noch was anderes gefunden: Man könnte das Ganze auch mit Radiobuttons machen und "indicatoron=0" verwenden.
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
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()
lG
dh233