PyQt:窗口在收听ip,port时停止响应

时间:2016-06-08 07:52:34

标签: python sockets pyqt qtimer

我正在尝试使用套接字创建一个简单的聊天应用程序,当我尝试一个简单的事情,制作一个循环并听取我的主机名和端口时,GUI将开始冻结并且根本不会响应。

但是,我也试过QTimer(),因为它是为PyQt设计的,但它会带来相同的结果并冻结窗口。

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

10秒后(超时发生时),它开始冻结窗口,问题可能是什么?我需要分离流程吗?还有其他更好的解决方案吗?

2 个答案:

答案 0 :(得分:2)

很可能问题出现了,因为你只在主应用程序中连接套接字,这会拖延包括GUI在内的整个过程。 因此,使用subprocess模块和multiprocessing模块在​​单独的流程中运行套接字功能和聊天功能的解决方案更好。

通过使用这些,您将在不同的过程中运行sockect应用程序,除了主GUI过程,并且两者都将平行工作而不会拖延主应用程序

答案 1 :(得分:1)

您需要在不同的线程中进行GUI和通信。当套接字例如等待某些数据时,GUI被阻止。您可以使用QT的信号/插槽连接两个线程。

例如,Example是GUI的类。 MyThread将在另一个线程中运行并每秒调用一个Example的插槽。     导入系统     来自PyQt4导入QtGui,QtCore     进口时间     导入线程

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()

有关信号/广告位的更多文档http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html

注意在上面的示例中,您需要在退出应用程序之前完成MyThread.process函数。这可以通过将should_continue变量转换为false

来完成