簡體   English   中英

QtUdpSocket關閉MainWindow后仍在偵聽端口

[英]QtUdpSocket still listening on port after closing MainWindow

我有一個QWidgetudpWidget在實例化) QMainWindowudpMainWindow )。 我正在從另一個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”按鈕關閉時,該端口不會釋放。 然后,當您嘗試使用“主主窗口”進行監聽時,由於它仍在使用中,因此無法綁定。

重現問題的步驟:

  1. 運行程序
  2. 在“ UDP主窗口”上單擊“偵聽端口12345”
  3. *單擊“主主窗口”上的“偵聽端口12345” *(這只是確認該端口正忙,不需要重現問題。
  4. 單擊“ x”關閉“ UDP主窗口”
  5. 單擊“主主窗口”上的“偵聽端口12345”,這將現在無法連接。

編碼

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM