[PyQt] Problem mit Dialog & Endlosschleife

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hallo.
Ich habe mir mit PyQt einen Dialog gebastelt, er eine einfache TextBox enthält.
Das ganze funktioniert auch wunderbar. Nun will ich diesen Dialog als Server laufen lassen - also brauche ich eine Endlosschleife (soweit ich bis jetzt weiß).

Nur das Problem: Solange der Dialog auf ist, bleibt der Server in einer Schleife vom Dialog und springt erst zu meiner Endlosschleife wenn der Dialog geschlossen wird. Wenn ich die Endlosschleife vor dem initialisieren des Dialogs packe, lädt der Dialog nicht - logisch.

Kann man dies irgendwie lösen?

Hier ist mein bisheriger Code:

Code: Alles auswählen

import sys, socket, thread
from PyQt4 import QtCore, QtGui
from Server import Ui_Dialog as Dialog_Server

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 1234))
s.listen(1)

print "Listener geoeffnet auf Port 1234!"

while True:
	nachricht, adresse = s.accept()
	
	while True:
		text = nachricht.recv(1024)
		
		if text != "":
			print "%s sagt: %s" % (adresse[0], text)

class Fenster(QtGui.QDialog, Dialog_Server): 
	def __init__(self): 
		QtGui.QDialog.__init__(self) 
		self.setupUi(self)
		
		self.connect(self.Schliessen, QtCore.SIGNAL("clicked()"), self.Schliessen_Click)
	
	def Schliessen_Click(self):
		try:
			s.close()
			close()
		except:
			print "Konnte Server nicht beenden!"

App = QtGui.QApplication(sys.argv)
Dialog = Fenster()
Dialog.show()
sys.exit(App.exec_())

while True:
	nachricht, adresse = s.accept()
	
	while True:
		text = nachricht.recv(1024)
		
		if text != "":
			print "%s sagt: %s" % (adresse[0], text)
EDIT: Mir fällt gerade auf, dass alles was ich vom Client zum Server sende, mit einem Leerzeichen versehen wird. So wird aus "Hallo :)" "H a l l o : )" - woran liegt das?

Danke,
~ Chris
Grüßle.
BlackJack

Da msn nicht sieht wie Du was sendest, kann man bei den Leerzeichen nur raten.
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Aso, dachte das liegt am Server :/

Code: Alles auswählen

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

class Fenster(QtGui.QDialog, Dialog_Chat): 
	def __init__(self): 
		QtGui.QDialog.__init__(self) 
		self.setupUi(self)
		
		self.connect(self.Senden, QtCore.SIGNAL("clicked()"), self.Senden_Click)
		
		try:
			s.connect(("192.168.2.101", 1234))
			self.Chat.setPlainText("Verbindung mit 192.168.2.101:1234 hergestellt!")
		except:
			self.Chat.setPlainText("Verbindung mit 192.168.2.101:1234 konnte nicht vergestellt werden!")
			self.Senden.setEnabled(False)
	
	def Senden_Click(self):
		try:
			self.Chat.setPlainText("%s\n192.168.2.101: %s" % (self.Chat.toPlainText(), self.Nachricht.text()))
			
			s.send(self.Nachricht.text())
			self.Nachricht.setText("")
		except:
			s.close()
			self.Senden.setEnabled(False)
			
			self.Chat.setPlainText("%s\nNachricht konnte nicht gesendet werden, Verbindung getrennt!" % self.Chat.toPlainText())
~ Chris
Grüßle.
lunar

Eine geschachtelte Endlosschleife ist ziemlich sinnlos, da eh nur die innere Schleife läuft.

Zeile 30 wirft einen NameError, da ``close`` nirgendwo gebunden wird.

Dein Problem ist, dass Qt selbst bereits eine Endlosschleife startet, um Ereignisse zu behandeln. Du musst deinen Server-Code folglich in die Eventschleife integrieren. Das geht auf die harte Tour über Threading, oder auf einfache Weise über die Klassen aus dem ``QNetwork`` Modul.

Was die Leerzeichen angeht: Ohne den Code, der sendet, kann ich da nichts zu sagen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Für netzwerkprogrammierung mit Twisted gibt es QTReactor, der bindet sich in die Event-Loop ein (findet ihr die Begründung warum es nicht Teil des Releases ist auch so sinnlos wie ich?).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

@ lunar: Hab den Code doch gepostet? Und Z. 30 funktioniert bei mir einwandfrei!
@ Leonidas: Danke, werde mir dass mal anschauen :)

Danke,
~ Chris
Zuletzt geändert von theliquidwave am Samstag 7. Juni 2008, 12:13, insgesamt 1-mal geändert.
Grüßle.
lunar

Oh ja, es ist natürlich auch eine hervorragende Idee, eine weitere dicke Abhängigkeit zu einem ziemlich komplexen Framework hinzuzufügen, nur um Daten über ein normales Socket zu versenden, vor allem, wenn es im verwendeten GUI-Framework bereits Socket-Klassen gibt ...

@Chrisber
Jo, der war allerdings noch nicht da, als ich mein Posting geschrieben habe ;)

Und wenn Zeile 40 bei dir einwandfrei funktioniert, ist der Code, den du ausführst, nicht der, den du hier gepostet hast.
BlackJack

@Chrisber: Bei dem Code zum senden steht ``self.Nachricht.text()``, da solltest Du mal schauen was da *genau* gesendet wird. Ich nehme mal an, das ist ein GUI-Element. Sollten die nicht Unicode-Objekte liefern? Wie wird das denn kodiert? Was passiert wenn Du versuchst einen Umlaut zu senden?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Oh ja, es ist natürlich auch eine hervorragende Idee, eine weitere dicke Abhängigkeit zu einem ziemlich komplexen Framework hinzuzufügen, nur um Daten über ein normales Socket zu versenden, vor allem, wenn es im verwendeten GUI-Framework bereits Socket-Klassen gibt ...
Wir wollen ja mal so tun als hätte Twisted natürlich auch keinerlei Nutzen. Stimmt, warum schlag ich so etwas auch vor, wenn Qt doch Sockets hat!
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Hey, versteh mich nicht falsch, Twisted ist sinnvoll. Aber sag selbst, sieht der Code des OP auch nur entfernt so aus, als würde er von der Mächtigkeit von Twisted tatsächlich profitieren? Oder glaubst du nicht eher auch, dass Twisted hier nur Over Engineering wäre, und mehr dazu geeignet, den OP zu verwirren, als ihm zu helfen? ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Aber sag selbst, sieht der Code des OP auch nur entfernt so aus, als würde er von der Mächtigkeit von Twisted tatsächlich profitieren? Oder glaubst du nicht eher auch, dass Twisted hier nur Over Engineering wäre, und mehr dazu geeignet, den OP zu verwirren, als ihm zu helfen? ;)
Sagen wir es mal so: es hängt ab. Über den vom OP geposteten Code werde ich nicht urteilen, da der OP nicht gesagt hat, was das ganze eigentlich insgesammt werden kann. Wenn es eine Chat-Applikation werden soll oder zumindest Netzwerkkommunikation mehr als nur einen Bruchteil der Funktionalität ausmacht könnte Twisted da Sinn machen (zumindest die Kernkomponenten) - einfache Protokolle damit zu schreiben ist weniger fehleranfällig und effizienter als mit Sockets.

Andererseits hast du schon recht, dass wenn es wirklich nur irgendein Kleinkram ist, dass Twisted dann Overkill ist.

Aber immerhin, ich werd mal nachfragen ob man den QtReactor nicht neulizensieren kann und einbinden kann, das wäre sicherlich nicht verkehrt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Also dass mit den Unicode-Objekten vom GUI weiß ich nicht. Ich weiß nur, dass wenn ich ``print self.Nachricht.text()`` mache, dass dort keine Leerzeichen sind.

@ Leonidas: Sorry, aber der Code ist zu 100% gleich zu dem, den ich benutze, und Zeile 30 gibt mir keinen Fehler :/

Aus dem QtReactor werde ich überhaupt nicht schlau. In dem Beispiel ist so viel verwirrendes Zeugs ^^

Wie würde dass denn mit Threads gehen? Oder ratet ihr mir davon ab?

Danke schon mal,
~ Chris
Grüßle.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Chrisber hat geschrieben:Aus dem QtReactor werde ich überhaupt nicht schlau. In dem Beispiel ist so viel verwirrendes Zeugs ^^
Der QTReactor ist nur notwendig, wenn du Twisted verwenden willst. Du hast uns aber bisher nicht gesagt was du eigentlich machen willst, also kann man auch nicht abschätzen, ob dir Twisted was bringen würde.
Zuletzt geändert von Leonidas am Montag 9. Juni 2008, 09:07, insgesamt 1-mal geändert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Also ich wollte eigentlich nur einen simplen Chat scripten, zum üben halt.
Dann immer mehr Features dazu - man lernt ja schließlich auch. (z.B. Bann-Funktion oder Smileys etc.)

Danke,
~ Chris
Grüßle.
lunar

Chrisber hat geschrieben:Sorry, aber der Code ist zu 100% gleich zu dem, den ich benutze, und Zeile 30 gibt mir keinen Fehler :/
Doch, das tut es. Wenn der Server läuft, wirst du jedes mal "Konnte Server nicht beenden!" sehen, weil dein reines ``except`` in Zeile 31 auch den ``NameError`` abfängt.

Nichts für ungut, aber wenn dir diese Grundlagen bei der Ausnahmebehandlung fehlen und dir offenbar nicht bewusst ist, dass man Instanzmethoden nur über ``self`` aufrufen kann, dann solltest du besser noch mal das Tutorial und ABOP durcharbeiten, bevor du gleich einen ganzen Chat implementierst ;)
Wie würde dass denn mit Threads gehen? Oder ratet ihr mir davon ab?
Ja. Threads sind erstens unnötig, und zweitens bezweifele ich, dass du mit Threads zurecht kommen würdest... nichts für ungut ;)

Am einfachsten löst du das mit den Klassen des ``QtNetwork``-Moduls, auf die ich dich bereits hingewiesen habe ;) Hier hast du ein kleines Beispiel.
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Ja sorry, hast recht ^^
Immer wenn ich das Programm per python ausführe, und ich den Chat beende, dachte ich, dass funktioniert, aber wenn man genau hinschaut ist da für ne halbe Sekunden eine Fehlermeldung, dann geht das Fenster zu :/

Gibt es da eine Möglichkeit, dass Fenster offen zu lassen, um die Fehlermeldung zu lesen?
Das mit dem Close ist jetzt aber gefixt :)

Und danke für den Link, werde mir das mal anschauen :D

~ Chris
Grüßle.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Chrisber hat geschrieben:Gibt es da eine Möglichkeit, dass Fenster offen zu lassen, um die Fehlermeldung zu lesen?
Ja, in der Konsole starten. Steht auch in den FAQ.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Vielen Dank und Sorry für die unnötigen Fragen :?

~ Chris
Grüßle.
Antworten