ShellRox
ShellRox

Reputation: 2602

PyQt: Window stops responding when listening to ip, port

I am trying to make a simple chat application with sockets, When i tried a simple thing, making a loop and listening to my hostname and port, GUI would start freezing and would not respond at all.

However, i also tried a QTimer(), since it is designed for PyQt, but it would bring a same result and freeze the window.

def startloop(self):
    IP = socket.gethostbyname(socket.gethostname())
    self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    self.s.bind((IP, 5005))
    self.loop = QtCore.QTimer(self)
    self.loop.timeout.connect(self.check)
    self.loop.start(10000)

def recv(self):
    data, addr = self.s.data.recvfrom(1024)
    print data

After every 10 seconds (when timeout occurs), It starts freezing the window, what may the problem be? do i need to seperate processes? Is there any other better solution to do so?

Upvotes: 1

Views: 1491

Answers (2)

SnoozeTime
SnoozeTime

Reputation: 353

You need to do the GUI and the communication in different threads. When the socket is for example waiting for some data, the GUI is blocked. You can connect the two threads using signal/slots of QT.

For example, Example is the class for GUI. MyThread will run in another thread and call a slot of Example every seconds. import sys from PyQt4 import QtGui, QtCore import time import threading

class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
        btn = QtGui.QPushButton('Button', self)
        self.show()
        self.background = MyThread(self)
        t = threading.Thread(target=self.background.process)
        t.start()
        self.background.notify.connect(self.notify)

    @QtCore.pyqtSlot()
    def notify(self):
        print("I have been notified")

class MyThread(QtCore.QObject):

    notify = QtCore.pyqtSignal()

    def __init__(self, parent):
        super(MyThread, self).__init__(parent)
        self.should_continue = True

    def process(self):
        while self.should_continue:
            # Here, do your server stuff.
            time.sleep(1)
            self.notify.emit()

def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

More doc on Signal/Slots http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html

Note In the example above, you will need the MyThread.process function to finish before quitting the application. This can be done by turning the should_continue variable to false

Upvotes: 1

bmonikraj
bmonikraj

Reputation: 52

Most probably the problem is occuring because you connecting the socket in the main application only which is stalling the whole process including the GUI. So the solution is better you run socket function and chat function in a separate process using subprocess module and multiprocessing module.

By using these, you will be running the sockect application in different process, apart from the main GUI process, and both will parallely work without stalling the main application

Upvotes: 2

Related Questions