我在QWidget
(udpWidget
)中实例化QMainWindow
(udpMainWindow
)。我正在从另一个udpMainWindow
QMainWindow
发生了一些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主窗口"使用PushButton,然后关闭使用' X'按钮,端口没有释放。然后,当您尝试使用" Main Main Window"它无法绑定,因为它仍在使用中。
重现问题的步骤:
守则
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_()
答案 0 :(得分:2)
通常情况下,如果您不关闭套接字,那么在您退出应用程序之前它将不会关闭。关闭窗口是不够的,套接字属于应用程序而不属于窗口(两个窗口在同一个进程中)。 如果要关闭套接字,则必须确定将其放在何处。
如果要在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_()