The most important problem is that both Tkinter and Twisted solve similar problems in a similar way, namely they respond asynchronously to external events. The fact that Tkinter is focused on gui and Twitsted events on network events is extremely important.
The specific thing that they do is that they have a βmain loopβ structure, a kind of point from where there is no return from which you lose control. In case of twisting, usually reactor.run() , and in tkinter it will be Tkinter.mainloop() . Both will not return until the program exits.
Fortunately, you can get Twisted up to manage the tk event loop for you! At the beginning of your program, you should add:
from Tkinter import Tk from twisted.internet import tksupport root_window = Tk() tksupport.install(root_window)
then, once you have created your gui as usual, you should not call Tkinter.mainloop() , use:
from twisted.internet import reactor root_window.protocol("WM_DELETE_WINDOW", reactor.stop) reactor.run()
The odd bit with Tk.protocol() is optional, but will get rid of some terrible exceptions by shutting down the reactor normally when gui tries to exit.
In case this is not enough, here is some real working code! First a really simple server
from twisted.internet.protocol import Protocol, Factory from twisted.internet import reactor class Echo(Protocol): def dataReceived(self, data): print 'recieved:', data def connectionLost(self, reason): print 'connection closed', reason f = Factory() f.protocol = Echo reactor.listenTCP(8080, f) reactor.run()
and client with gui and network activity:
from Tkinter import * from twisted.internet import tksupport, reactor master = Tk() tksupport.install(master) def send_message(): message = e1.get() reactor.connectTCP("localhost", 8080, MessageCFactory(message)) print("message: %s" % (message)) Label(master, text="Message").grid(row=0) e1 = Entry(master) e1.grid(row=0, column=1) Button(master, text='Send', command=send_message).grid(row=3, column=1, sticky=W, pady=4) from twisted.internet.protocol import ClientFactory, Protocol from twisted.internet import reactor class MessageCProto(Protocol): def connectionMade(self): self.transport.write(self.factory.message) self.transport.loseConnection() class MessageCFactory(ClientFactory): protocol = MessageCProto def __init__(self, message): self.message = message master.protocol("WM_DELETE_WINDOW", reactor.stop) reactor.run()