dimanche 12 juin 2016

QtUdpSocket still listening on port after closing MainWindow

I have a QWidget (udpWidget) instantiated in a QMainWindow (udpMainWindow). I am creating udpMainWindow from another QMainWindow

There is some ValueError exception occurring (which I am going to fix). When I close the window of udpMainWindow, I can no longer do a bind to the port until I close the entire program. I understand I need to fix the exception that is occurring, however I don't understand why after closing the udpMainWindow that the resource (0.0.0.0:12345) is still listening.

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)

Edit 1:

Here is a fully functional example. When you start listening on the "UDP Main Window" using the PushButton, then close using the 'X' button, the port doesn't free up. Then when you attempt to listen with the "Main Main Window" it fails to bind because it is still in use.

Steps to reproduce problem:

  1. Run Program
  2. Click "Listen to port 12345" on "UDP Main Window"
  3. *Click "Listen to port 12345" on "Main Main Window" *(this just confirms that the port is busy, not necessary to reproduce problem.
  4. Click 'x' to close "UDP Main Window"
  5. Click "Listen to port 12345" on "Main Main Window" This will now fail to connect.

The Code

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

Aucun commentaire:

Enregistrer un commentaire