You have the right idea about what is causing the hang.
Whether you continue to use python sockets, or switch to using twisted, you will be faced with the same situation. Creating QWidgets and calling their method must be done in the main GUI thread. Other threads doing work need to communicate using signals/slots, which will queue up operations into the main thread for execution.
Your Listen thread starts running and waiting for connections. When a connection happens from a client, the server accepts it and runs your MessageHandler for the request. This is still in a thread. I am assuming messageWindow() is creating a QWidget instance, and then DisplayMessage(msg) is trying to perform GUI operations directly on that object.
What you will want to do instead is emit signals when a message is received. Connect to this signal in your main gui thread with a slot that can receive the message and interact with your QWidget that you want to show.
The python SocketServer, I think, makes it a little more complicated because the handler is a separate object from the server, and your server is hidden away as a member of the thread. The first question is really whether you need every connection to be a separate thread because they do a bunch of work or not. If all they are doing is connecting, sending some text, and disconnecting, it can really just be a server running in a thread which accepts messages synchronously.
Anyways, here is an example that just tweaks what you already have:
We make your Listen thread -> QThread to gain the ability to emit signals and still be a thread all in one.
We make your TCP_Messaging class -> QObject to also emit signals.
The idea being that the handler reads the message and emits a messageReceived signal. We have to be a little hacky because the handler only knows about the server and the server is not a a QObject, so really what I did was just copy the signal reference onto it so the handler can see it. What you could do is make your own SocketServer.TCPServer subclass that also inherits QObject, so that it can be the one to own the messageReceived signal. But thats up to you since this is just an example.
Then we expose another messageReceived signal to the world, on your TCP_Messaging class. All this does is connect from signal->signal on the server that is created when you call Connect(). The effect is that when a message is emitted from a handler, it goes to the server which is then forwarded out to the world.
So the usage is that you just start the server and connect a main thread slot to it for receiving messages.
A more compact and cleaner way of doing this same thing would be to just make your own Server class QObject which runs a loop of accepting clients and handling them, all in one place. This would make it much easier to just emit a signal from one public spot.
-- justin
On Dec 11, 2012, at 12:51 AM, PBLN RAO wrote:
<TCP_Chat_04.py>