关闭MainWindow

时间:2016-06-02 19:24:18

标签: python python-2.7 pyside

我在QWidgetudpWidget)中实例化QMainWindowudpMainWindow)。我正在从另一个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"它无法绑定,因为它仍在使用中。

重现问题的步骤:

  1. 运行程序
  2. 点击"收听端口12345"在" UDP主窗口"
  3. *点击"收听端口12345"在"主要主窗口" *(这只是确认端口正忙,没有必要重现问题。
  4. 点击' x'关闭" UDP主窗口"
  5. 点击"收听端口12345"在"主要主窗口"现在无法连接。
  6. 守则

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

1 个答案:

答案 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_()