Seite 1 von 1

Kleines Problem mit der "bind" Methode eines Widge

Verfasst: Mittwoch 26. August 2009, 15:13
von PNS-Richi
Hallo,

ich spiele mich gerade ein wenig mit tkinter und python. Nun, wenn ich auf den Radiobutton "deny" klicke kommt dieser Fehler:

Code: Alles auswählen

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python25\lib\lib-tk\Tkinter.py", line 1414, in __call__
    return self.func(*args)
TypeError: 'dict' object is not callable
Irgendwie steh ich grad auf der Leitung was im Quellcode nicht passt.

Code: Alles auswählen

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

from Tkinter import *
import os, sys

groups = {}

groups["room1"] = {}
groups["room1"]["192.168.10.251"] = "allow"
groups["room1"]["192.168.10.252"] = "allow"
groups["room1"]["192.168.10.253"] = "allow"
groups["room1"]["192.168.10.254"] = "allow"

groups["room2"] = {}
groups["room2"]["192.168.10.251"] = "allow"
groups["room2"]["192.168.10.252"] = "allow"
groups["room2"]["192.168.10.253"] = "allow"
groups["room2"]["192.168.10.254"] = "allow"

class App:

	def __init__(self, root):
		
		self.script_path = sys.path[0]
		print self.script_path
		print "%s\\allow.gif" % self.script_path
		self.piAllow = PhotoImage(file="%s\\allow.gif" % self.script_path)
		self.piDeny = PhotoImage(file="%s\\deny.gif" % self.script_path)
		
		row_count = 0
		
		self.lblGroup = {}
		self.lfGroup = {}
		self.allow = {}
		self.deny = {}
		self.lblIp = {}
		self.status = {}
		
		self.frame = Frame(root)
		self.frame.pack(padx=5, pady=5, anchor="nw")

		for group_entry in groups:
		
			self.lfGroup[group_entry] = LabelFrame(self.frame, text="Group: %s" % group_entry)
			self.lfGroup[group_entry].grid(row=row_count, column=0)

			#self.lblGroup[group_entry] = Label(root, text="Group: %s" % group_entry).grid(row=row_count, column=0)
			#self.allow[group_entry] = Button(root, text="Allow", command=self.allow, image=self.piAllow).grid(row=row_count, column=1)
			#self.deny[group_entry] = Button(root, text="Deny", command=self.deny, image=self.piDeny).grid(row=row_count, column=2)
			
			row_count += 1
			row_count2 = 0
			
			self.lblIp[group_entry] = {}
			self.deny[group_entry] = {}
			self.allow[group_entry] = {}
			self.status[group_entry] = {}
			
			for ip_entry in groups[group_entry]:
			
				self.lblIp[group_entry][ip_entry] = Label(self.lfGroup[group_entry], text="Ip: %s" % ip_entry)
				self.lblIp[group_entry][ip_entry].grid(row=row_count2, column=0)
				
				self.status[group_entry][ip_entry] = IntVar()
				
				#self.allow[ip_entry] = Button(self.lfGroup[group_entry], text="Allow", command=self.allow, image=self.piAllow)
				self.allow[group_entry][ip_entry] = Radiobutton(self.lfGroup[group_entry], text="Allow", command=self.allow, image=self.piAllow, variable=self.status[group_entry][ip_entry], value=1)
				self.allow[group_entry][ip_entry].grid(row=row_count2, column=1)
				
				#self.deny[ip_entry] = Button(self.lfGroup[group_entry], text="Deny", command=self.deny, image=self.piDeny)
				self.deny[group_entry][ip_entry] = Radiobutton(self.lfGroup[group_entry], text="Deny", image=self.piDeny, variable=self.status[group_entry][ip_entry], value=2)
				self.deny[group_entry][ip_entry].grid(row=row_count2, column=2)
				self.deny[group_entry][ip_entry].group_entry = group_entry
				self.deny[group_entry][ip_entry].bind("<Button-1>", self.deny)
				
				row_count2 += 1

		screenwidth = root.winfo_screenwidth()
		screenheight = root.winfo_screenheight()

		root.resizable(False, False)
		root.geometry('+%s+%s' % (int((screenwidth / 2) - (root["width"] / 2)), int((screenheight / 2) - (root["height"] / 2))))
	
		root.title('proxy.manager')
	def allow(self):
		pass
		
	def deny(self, event):
		print "test"
		#print event.widget.group_entry
		#pass

root = Tk()

app = App(root)

root.mainloop()
lg Richi

Verfasst: Mittwoch 26. August 2009, 15:26
von EyDu
Denk mal über die Zeilen 75, 36 und 89 nach ;-)

Du solltest übrigens unbedingt mal einen Blick in PEP 8 werfen und über Minimalbeispiele nachdenken.

Verfasst: Mittwoch 26. August 2009, 15:37
von PNS-Richi
Argh bin ich blind... Da sieht man die Funktion vor lauter Dicts nicht mehr.

Auf was in PEB 8 möchtest du mich den genau hinweisen?

lg

Verfasst: Mittwoch 26. August 2009, 16:25
von EyDu
PEP 8:
- Zeilenlängen
- Namen

Sonst:
- Du solltest keine *-Import benutzen. Besser "import Tkinter as tk".
- Das "groups" ist da etwas fehlplatziert. Wenn es eine Konstante ist, gehört der Name groß, sonst wahrscheinlich besser in eine Konfigurationsdatei.
- Wenn du Python in einer Version < 3 benutzt, dann sollte "App" von "object" erben. "App" ist auch ein sehr seltsamer Namen ;-)
- Zum Zusammensetzen von Pfaden benutze am besten "os.path.join". Alles andere ist fehleranfällig.
- Verwende keinen Code auf Modulebene. Das gilt besonders für die Zeilen ab 94. Erstelle besser eine main-Funktion und rufe sie dann so auf:

Code: Alles auswählen

if __name__ == "__main__":
    main()
Dann ist sichergestellt, dass dein Programm auch nur ausgeführt wird, wenn man es direkt startet. Dann kannst du das Modul auch importieren.
- Du könntest dich teilweise ein wenig kürzer fassen:

Code: Alles auswählen

spam = Radiobutton(self.lfGroup[group_entry], text="Deny", image=self.piDeny, variable=self.status[group_entry][ip_entry], value=2)
spam.grid(row=row_count2, column=2)
spam.group_entry = group_entry
spam.bind("<Button-1>", self.deny)
self.deny[group_entry][ip_entry] = spam

Verfasst: Donnerstag 27. August 2009, 11:01
von PNS-Richi
Hallo,

danke für deine Aufklärung. Ich gebe zu ich habe bei dem Beispiel einiges verhauen bzw. nicht auf die Struktur geachtet. Das ganze ist nur mal ne tkinter spielerei, deshalb ist es ein wenig chaotisch :P