[英]QtUdpSocket still listening on port after closing MainWindow
我有一個QWidget
( udpWidget
在實例化) QMainWindow
( udpMainWindow
)。 我正在從另一個QMainWindow
創建udpMainWindow
有一些ValueError
異常發生(我將要修復)。 關閉udpMainWindow
的窗口時,在關閉整個程序之前,無法再綁定到端口。 我知道我需要修復發生的異常,但是我不明白為什么在關閉udpMainWindow之后資源(0.0.0.0:12345)仍在偵聽。
class udpWidget(QtGui.QWidget):
def __init__(self, parent):
super(udpWidget, self).__init__(parent)
self.listenSocket=QtNetwork.QtUdpSocket()
...
def do_something(self)
self.listenSocket.bind(12345)
...
#Some Exception Occurs
self.listenSocket.close()
def destroy(self, destroyWindow, destroySubWindows):
self.listenSocket.close()
def closeEvent(self, event):
self.listenSocket.close()
event.accept()
class udpMainWindow(QtGui.QMainWindow):
def __init__(self, parent):
super(udpMainWindow, self).__init__(parent)
myUdpWidget=udpWidget(self)
myButton.clicked.connect(myUdpWidget.do_something)
編輯1 :
這是一個功能齊全的示例。 當您使用按鈕開始在“ UDP主窗口”上偵聽,然后使用“ X”按鈕關閉時,該端口不會釋放。 然后,當您嘗試使用“主主窗口”進行監聽時,由於它仍在使用中,因此無法綁定。
重現問題的步驟:
編碼
from PySide import QtGui, QtCore, QtNetwork
class udpWidget(QtGui.QWidget):
def __init__(self, parent):
super(udpWidget, self).__init__(parent)
self.listenSocket=QtNetwork.QUdpSocket()
#bindResult=self.listenSocket.bind(12345)
@QtCore.Slot()
def start_listening(self):
bindResult=self.listenSocket.bind(12345)
print "binding: {}".format(bindResult)
raise ValueError("invalid Number") #Simulate exception occuring.
self.listenSocket.close()
def destroy(self, destroyWindow, destroySubWindows):
print "udpWidget.destroy called"
self.listenSocket.close()
def closeEvent(self, event):
print "udpWidget.closeEvent called"
self.listenSocket.close()
event.accept()
class udpMainWindow(QtGui.QMainWindow):
def __init__(self, parent):
super(udpMainWindow, self).__init__(parent)
self.setWindowTitle("UDP Main Window")
self.myUdpWidget=udpWidget(self)
btn = QtGui.QPushButton("Listen to port 12345")
btn.clicked.connect(self.myUdpWidget.start_listening)
self.setCentralWidget(btn)
def closeEvent(self, event):
print "udpMainWindow.closeEvent called"
#self.myUdpWidget.listenSocket.close()
class mainMainWindow(QtGui.QMainWindow):
def __init__(self, parent):
super(mainMainWindow, self).__init__(parent)
self.setWindowTitle("Main Main Window")
myUdpMainWindow = udpMainWindow(self)
myUdpMainWindow.show()
self.listenSocket=QtNetwork.QUdpSocket()
btn = QtGui.QPushButton("Listen to port 12345")
btn.clicked.connect(self.connect_udp)
self.setCentralWidget(btn)
@QtCore.Slot()
def connect_udp(self):
bindResult=self.listenSocket.bind(12345)
print "binding: {}".format(bindResult)
if __name__=="__main__":
myApp = QtGui.QApplication([])
myMainMainWindow = mainMainWindow(None)
myMainMainWindow.show()
myApp.exec_()
通常,如果不關閉套接字,那么在退出應用程序之前不會關閉套接字。 關閉一個窗口是不夠的,套接字屬於應用程序而不是該窗口(兩個窗口在同一進程中)。 如果要關閉插槽,則必須決定在哪里進行操作。
如果要在start_listening函數末尾關閉套接字,則只需在可能發生異常的地方使用異常處理即可:
try:
# here is the part where exception can happen
raise ValueError("invalid Number") #Simulate exception occuring.
except ValueError:
# handle error here
self.listenSocket.close()
如果要在udpMainwindow的closeEvent中關閉它,則只需取消注釋該行
self.myUdpWidget.listenSocket.close()
在兩個窗口的此代碼中,關閉時將調用closeEvent:
from PySide import QtGui, QtCore, QtNetwork
class udpMainWindow(QtGui.QMainWindow):
def __init__(self, parent):
super(udpMainWindow, self).__init__(parent)
self.setWindowTitle("UDP Main Window")
self.listenSocket=QtNetwork.QUdpSocket()
#self.myUdpWidget=udpWidget(self)
btn = QtGui.QPushButton("Listen to port 12345")
btn.clicked.connect(self.start_listening)
self.setCentralWidget(btn)
def closeEvent(self, event):
print "udpMainWindow.closeEvent called"
#self.listenSocket.close()
@QtCore.Slot()
def start_listening(self):
bindResult=self.listenSocket.bind(12345)
print "binding: {}".format(bindResult)
try:
raise ValueError("invalid Number") #Simulate exception occuring.
except ValueError:
# handle error here
pass
finally:
self.listenSocket.close()
class mainMainWindow(QtGui.QMainWindow):
def __init__(self, parent):
super(mainMainWindow, self).__init__(parent)
self.setWindowTitle("Main Main Window")
myUdpMainWindow = udpMainWindow(self)
myUdpMainWindow.show()
self.listenSocket=QtNetwork.QUdpSocket()
btn = QtGui.QPushButton("Listen to port 12345")
btn.clicked.connect(self.connect_udp)
self.setCentralWidget(btn)
@QtCore.Slot()
def connect_udp(self):
bindResult=self.listenSocket.bind(12345)
print "binding: {}".format(bindResult)
def closeEvent(self, event):
print "mainMainWindow.closeEvent called"
#self.listenSocket.close()
if __name__=="__main__":
myApp = QtGui.QApplication([])
myMainMainWindow = mainMainWindow(None)
myMainMainWindow.show()
myApp.exec_()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.