Ich kann ja mal beginnen und zwar mit dem Zweck. Es geht um komplexe Anwendungen. Ein Teil der Anwendung soll eine Aktion im anderen Teil der Anwendung auslösen.
Wo dieser andere Teil ist, welche Widgets das sind und ob es überhaupt Widgets sind, ist diesem Teil aber nicht bekannt, und ob dieser bereits importiert oder sonstwie da ist, ist auch nicht bekannt.
Daher legt man so etwas fest, wie ein virtuelles Event, das eine Message ID hat und Daten die dabei mitgesendet werden. Sagen wir einmal, in der GUI, wo auch immer, soll ein Name und zwar mit Vorname und Nachname getrennt angezeigt werden.
Dann legt man eben fest, dass es eine Message gibt, die das tut, etwa mit:
Code: Alles auswählen
proxy.send('NAME',(vorname,nachname))
Also definiert man einen Callback, vielleicht auf zwei Label und das geschieht mit proxy.do_receive, etwa:
Code: Alles auswählen
def show_name(message,vname=label_vname,nname=label_nname):
vname['text'] = message[0]
nname['text'] = message[1]
proxy.do_receive(parent,'NAME',show_name)
Code: Alles auswählen
def __destroy__self(): proxy.undo_receiveAll(self)
Code: Alles auswählen
import proxy as myproxy
proxy = myproxy.Proxy()
Dann erklären wir einmal den Code. Um auch mit andern Tasks zu kommunizieren zu können, habe ich threadsichere Queues eingerichtet. Die eine ist für das normale Senden, die andere wird vorrangig behandelt für das Registrieren von Callbacks und das Deregistrieren.
Widmen wir uns einmal dem Senden:
Code: Alles auswählen
def send(self,msgid,msgdata=None):
self.Queue.put((msgid,msgdata))
self.trigger()
Code: Alles auswählen
self.trigger = self.do_work
Code: Alles auswählen
def do_work(self,*args):
if self.running: return
self.running = True
while self.work(): pass
self.running = False
Code: Alles auswählen
def work(self,*args):
if not self.Queue_HighPrio.empty(): data = self.Queue_HighPrio.get()
elif not self.Queue.empty(): data = self.Queue.get()
else: return False
Code: Alles auswählen
msgid = data[0]
msgdata = data[1]
if msgid in self.Dictionary:
receivers = self.Dictionary[msgid].items()
for receive,packed in receivers:
if packed: receive((msgid,msgdata))
else: receive(msgdata)
return True
Code: Alles auswählen
receive(msgdata)
Das wäre es mal im Groben. Und dann dürfte auch klar sein, dass do_receive Callbacks in dieses Dictionary einträgt und undo_receive sie wieder austrägt.
Hab gemerkt, dass da noch etwas fehlt für das Senden zu anderen Tasks. Muss die Registrierfunktionen doppelt machen für intern und extern. Beziehungsweise auch wieder nicht, da ich ja nicht zu anderen tkinter GUI Threads sende. Jedenfalls mal noch überdenken, ob man noch etas braucht, etwa wenn es nicht über den externen Proxy geht, sondern direkt mit einem anderen Thread. Naja, schreiben wir es einfach noch hinein, falls es doch mal jemand braucht.