PyQt:Window 监听 ip、端口时停止响应
PyQt: Window stops responding when listening to ip, port
我正在尝试用套接字制作一个简单的聊天应用程序,当我尝试一个简单的事情时,循环并监听我的主机名和端口,GUI 将开始冻结并且根本不会响应。
然而,我也尝试了 QTimer()
,因为它是为 PyQt 设计的,但它会带来相同的结果并冻结 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
每隔 10
秒(发生超时时),它开始冻结 window,可能是什么问题?我需要分开进程吗?还有其他更好的解决方案吗?
问题的发生很可能是因为您仅在主应用程序中连接套接字,这会拖延包括 GUI 在内的整个过程。
所以解决方案最好是 运行 套接字功能和聊天功能在单独的进程中使用 subprocess module and multiprocessing 模块。
通过使用这些,您将 运行在不同的进程中运行 sockect 应用程序,除了主 GUI 进程,并且两者将并行工作而不会停止主应用程序
您需要在不同的线程中进行 GUI 和通信。例如,当套接字正在等待某些数据时,GUI 会被阻塞。您可以使用 QT 的 signal/slots 连接两个线程。
例如,示例是 GUI 的 class。 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()
关于 Signal/Slots http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html
的更多文档
注意 在上面的示例中,您需要 MyThread.process 函数在退出应用程序之前完成。这可以通过将 should_continue 变量设置为 false
来完成
我正在尝试用套接字制作一个简单的聊天应用程序,当我尝试一个简单的事情时,循环并监听我的主机名和端口,GUI 将开始冻结并且根本不会响应。
然而,我也尝试了 QTimer()
,因为它是为 PyQt 设计的,但它会带来相同的结果并冻结 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
每隔 10
秒(发生超时时),它开始冻结 window,可能是什么问题?我需要分开进程吗?还有其他更好的解决方案吗?
问题的发生很可能是因为您仅在主应用程序中连接套接字,这会拖延包括 GUI 在内的整个过程。 所以解决方案最好是 运行 套接字功能和聊天功能在单独的进程中使用 subprocess module and multiprocessing 模块。
通过使用这些,您将 运行在不同的进程中运行 sockect 应用程序,除了主 GUI 进程,并且两者将并行工作而不会停止主应用程序
您需要在不同的线程中进行 GUI 和通信。例如,当套接字正在等待某些数据时,GUI 会被阻塞。您可以使用 QT 的 signal/slots 连接两个线程。
例如,示例是 GUI 的 class。 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()
关于 Signal/Slots http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html
的更多文档注意 在上面的示例中,您需要 MyThread.process 函数在退出应用程序之前完成。这可以通过将 should_continue 变量设置为 false
来完成