Search code examples
pythonsocketspysideqtexteditqplaintextedit

PySide QTextEdit or QPlainTextEdit update faster?


I am now trying to make a GUI on my PC communicate with a Server per sockets.

here is part of the code of GUI:

def listenToServer(self):
    """ keep listening to the server until receiving 'All Contracts Finished' """
    self.feedbackWindow.appendPlainText('--Executing the Contracts, Listening to Server--')
    contentsListend = ''
    while contentsListend != 'All Contracts Finished':
        #keep listen from the socket
        contentsListend = self.skt.recv(1024)
        #make the GUI show the text
        self.feedbackWindow.appendPlainText(contentsListend)

On the Other side, the server will send data one by one but with some interval. Here is the test code simulating the server:

for i in range(7):
    print 'send back msg, round: ', i # this will be printed on the screen of the server, to let me know that the server works
    time.sleep(1) # make some interval
    # c is the connected socket, which can send messages
    # just send the current loop number
    c.send('send back msg' + str(i))
c.send('All Contracts Finished')
c.close()# Close the connection

Now, everything works except the problem that, the GUI will only show the received messages after the whole for loop in the server. Once I run the server and the GUI. The server side print the messages onto the screen with correct speed one by one, but the GUI has no response, it does not update. Till the end of the program, all the 7 lines occurs all at once at GUI side. I want them to appear one by one, so that later I can inspect the state of the server with this GUI on my PC.

Can anybody help, thanks a lot!


Solution

  • This has nothing to do with "fast" or "slow".

    The GUI runs on the same thread as your listenToServer method - so as long as it's running nothing can happen on the GUI thread. You'll notice that you can't move, resize or click anything in the GUI while you're waiting socket input.

    You'll have to run your listenToServer method on a thread separate from the GUI. The proper way to do that would be to implement a Worker object that receives data from the socket and notifies you textEdit via a Signal->Slot connection that there's data ready to receive.

    I answered a similar question a while back, that might help https://stackoverflow.com/a/24821300/2319400

    A really quick and dirty alternative would be to process all queued events when you've appended new data, via:

    QApplication.processEvents()
    

    This gives Qt time to e.g. repaint the GUI on the screen with new text. Your GUI will however not respond to any events while python is waiting for data to come from the socket!