Reputation: 2602
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
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
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