Kleines Problem mit der "bind" Methode eines Widge

Fragen zu Tkinter.
Antworten
PNS-Richi
User
Beiträge: 68
Registriert: Donnerstag 17. Januar 2008, 01:48

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
PNS-Richi
User
Beiträge: 68
Registriert: Donnerstag 17. Januar 2008, 01:48

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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
Das Leben ist wie ein Tennisball.
PNS-Richi
User
Beiträge: 68
Registriert: Donnerstag 17. Januar 2008, 01:48

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
Antworten