2016-06-08 10 views
0

Ich versuche, eine einfache Chat-Anwendung, mit Steckdosen zu machen, wenn ich eine einfache Sache versucht, macht eine Schleife und hören meine Hostnamen und Port, GUI Einfrieren beginnen würde, und würde überhaupt nicht antworten.PyQt: Fenster nicht mehr reagiert, wenn auf IP hören, Port

Allerdings probierte ich auch eine QTimer(), da es für PyQt entwickelt wurde, aber es würde ein gleiches Ergebnis bringen und das Fenster einfrieren.

def startloop(self): 
    IP = socket.gethostbyname(socket.gethostname()) 
    self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    self.s.bind((IP, 5005)) 
    self.loop = QtCore.QTimer(self) 
    self.loop.timeout.connect(self.check) 
    self.loop.start(10000) 

def recv(self): 
    data, addr = self.s.data.recvfrom(1024) 
    print data 

Nach jeweils 10 Sekunden (wenn Timeout auftritt), Es beginnt das Fenster einfrieren, was kann das Problem sein? muss ich Prozesse trennen? Gibt es noch eine andere bessere Lösung?

+1

UI und blockierenden Socket-Kommunikation sein, sollte nicht in dem gleichen Thread erfolgen. Wenn der Socket wartet, wird die GUI ebenfalls blockiert. Versuchen Sie es mit einem anderen Thread für die Sockets und kommunizieren Sie mit der GUI über Signal/Slots – SnoozeTime

+0

Danke @SnoozeTime aber ich bin nicht sehr vertraut mit pyqtslot, kann ich ein Beispiel bekommen, wie würde ich es tun? – ShellRox

Antwort

0

Sie müssen die GUI und die Kommunikation zu tun in verschiedene Themen. Wenn der Socket beispielsweise auf einige Daten wartet, ist die GUI blockiert. Sie können die zwei Threads über das Signal/die Slots von QT verbinden.

Zum Beispiel ist Beispiel die Klasse für GUI. MyThread wird in einem anderen Thread ausgeführt und ruft jeden Sekunde einen Slot von Beispiel auf. import sys von PyQt4 Import QtGui, QtCore Importzeit Import Threading

class Example(QtGui.QWidget): 

    def __init__(self): 
     super(Example, self).__init__() 
     QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10)) 
     btn = QtGui.QPushButton('Button', self) 
     self.show() 
     self.background = MyThread(self) 
     t = threading.Thread(target=self.background.process) 
     t.start() 
     self.background.notify.connect(self.notify) 

    @QtCore.pyqtSlot() 
    def notify(self): 
     print("I have been notified") 

class MyThread(QtCore.QObject): 

    notify = QtCore.pyqtSignal() 

    def __init__(self, parent): 
     super(MyThread, self).__init__(parent) 
     self.should_continue = True 

    def process(self): 
     while self.should_continue: 
      # Here, do your server stuff. 
      time.sleep(1) 
      self.notify.emit() 

def main(): 

    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

Mehr doc auf Signal/Slots http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html

Hinweis Im Beispiel oben, müssen Sie die Funktion MyThread.process zu beenden, bevor Sie die Anwendung beenden. Dies kann durch Drehen des should_continue Variable auf false

+0

Dank hinkt aus, funktioniert! – ShellRox

1

Wahrscheinlich das Problem auftreten, weil Sie die Steckdose in der Hauptanwendung verbindet nur die den gesamten Prozess einschließlich der GUI stockt. So ist die Lösung ist besser, Sie Socket-Funktion und Chat-Funktion in einem separaten Prozess mit subprocess Modul und multiprocessing Modul ausführen.

Durch diese verwenden, werden Sie die sockect Anwendung in verschiedenen Verfahren ausgeführt werden, abgesehen von der Haupt-GUI-Prozess, und beide werden die Arbeiten parallel, ohne dass die Hauptanwendung Abwürgen

+0

Ich habe versucht, mit Multiprozessor-Bibliothek mehr Prozesse zu machen, aber schien nicht zu arbeiten. 'Def start(): \t app = QtGui.QApplication (sys.argv) \t GUI = Window() \t sys.exit (app.exec_()) \t p1 = Prozess (target = self.authcheck) \t p1.start() \t p2 = Prozess (target = self.recv) \t p2.start() start() 'Es wäre noch – ShellRox

Verwandte Themen