我正在尝试使用套接字创建一个简单的聊天应用程序,当我尝试一个简单的事情,制作一个循环并听取我的主机名和端口时,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
秒后(超时发生时),它开始冻结窗口,问题可能是什么?我需要分离流程吗?还有其他更好的解决方案吗?
答案 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
来完成