2016-06-02 8 views
0

(udpMainWindow)으로 인스턴스화 된 QWidget (udpWidget)이 있습니다. 나는 udpMainWindow을 다른 사람에게서 창조하고있다 QMainWindowMainWindow를 닫은 후에 QtUdpSocket이 여전히 포트에서 수신 대기 중입니다.

어떤 ValueError 예외가 발생한다 (나는 고칠 예정이다). udpMainWindow의 창을 닫을 때 전체 프로그램을 닫을 때까지 더 이상 포트에 바인드 할 수 없습니다. 내가 발생하는 예외를 해결할 필요가 있지만 리소스 (0.0.0.0:12345) 여전히 듣고있는 udpMainWindow 닫은 후 이유를 이해하지 않지만 이해해야합니다.

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'버튼을 사용하여 닫으면 포트가 비어 있지 않습니다. 그런 다음 "Main Main Window"로 청취하려고하면 아직 사용 중이기 때문에 바인딩에 실패합니다.

  • 이 * 클릭 "메인 주 창"의 "포트 12345을 들어", "UDP 메인 창"에

    1. 프로그램 실행
    2. 클릭 "포트 12345을 들어"

      단계 문제를 재현하는 방법 * (이것은 단지 포트가 문제를 재현하는 데 필요한, 바쁜 아니라는 것을 확인합니다.

    3. 클릭 'X'는 "메인 주 창"의 "UDP 메인 창"
    4. 클릭 "포트 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_() 
    
  • +0

    제공 한 내용에 따라 updMainWindow가 닫힐 때 self.listenSocket.close()를 호출하는 내용이 표시되지 않습니다. do_something()이 실행될 때 우리는 절대 예외가 발생하지 않습니다. destroy() 및 closeEvent() 모두 소켓을 닫지 만, 그 중 하나가 updMainWindow.close()에서 호출 될 것이라고 확신하지는 않습니다. do_something이 소켓에서 close를 호출하지 못하게하는 예외를 해결하면됩니다. –

    +0

    또한 "udpMainWindow 닫기"는 updMainWindow 객체에서 close 메서드를 호출하는지 또는 표시창의 창 모서리에서 X 닫기를 클릭하여 보이는 창이 닫히는 지 여부가 명확하지 않습니다. 소켓에서 청취 할 때, 그것은 실제로 당신을 경청하는 OS입니다. 소켓에서 닫기를 호출하거나 프로세스를 종료하여 중지 할 때까지 계속 듣습니다. –

    +0

    @TomBarron 예, '예외'를 ​​수정하여 닫기가 호출됩니다. 나는 UDP 객체가 윈도우가 닫힌 후에도 여전히 포트에 붙어있는 것처럼 보이는 것에 대해 더 걱정했다. 그것은 내가 예상했던 방식대로 행동하지 않는다는 것 이상입니다. –

    답변

    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에 닫으려면 단순히 닫을 때 closeEvent가 호출 모두 창문이 코드에서 줄

    self.myUdpWidget.listenSocket.close() 
    

    의 주석 :

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

    해답을 보내 주셔서 감사합니다. 그러나 나는 실제로 내가 '시도 : 예외 : 마침내 :'문제를 인식 할 수 있기 때문에 실제로 내가 찾고있는 것에 대답하지 않습니다. (btw)'self.listenSocket.close()'를'finally :'절에 넣고 다른 문제가 발생했다면 실행되도록하거나 예외 처리기가 발생하는 지 확인하십시오. 그렇습니다. 그 줄의 주석 처리를 제거하면 문제를 해결할 수 있다는 것을 알아 두십시오. 그 코드를 해결하기 위해 코드에 넣은 줄입니다. –

    +0

    예, finally 절에 넣을 수 있습니다. 그러나 결정을 시도해보십시오. 그것은 아마도 당신의 예외가 일어나는 부분을 따르지 않을 수 있습니다. 그래서 나는 그것을 썼습니다. 그 옆에 나는 또한 당신에게 설명을 주었고, 왜 그렇게 행동 했습니까? 그밖에 또 무엇이 필요합니까? – quantummind

    +0

    내 후속 조치는 다음과 같습니다. Window가 닫힐 때'closeEvent' 나'destroy' 이벤트가 호출 된 이유를 모르겠습니다. 또한 Window에서 생성 된'QtNetwork.QUdpSocket' 객체가 애플리케이션에 속할 것이라고 생각하지 않습니다. 나에게 위젯의 부모가 U에 대해 알아야한다는 것은 이해가 가지 않는다. dpSocket. 이유에 대한 귀하의 설명은 훌륭하지만, 귀하가 제공하는 해결책은 이미 문제입니다. –

    관련 문제