etwas kurz vor destroyed ausführen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
usingKarmicKoala
User
Beiträge: 27
Registriert: Samstag 28. November 2009, 15:58

Ist es möglich noch eine Methode auszuführen wenn ich ein Fenster schließe? In meinem Fall soll beim schließen noch eine Nachricht an einen Server geschickt werden. Das Problem ist nur, dass wenn ich versuche das socket aufzurufen um die Nachricht zu schicken, dieses schon gelöscht ist.
Ich versuche es mit

Code: Alles auswählen

self.destroyed.connect(self.onExit)

...

def onExit(self):
      self.socket.write("Hallo Welt")
Muss ich ein anderes SIGNAL benutzen? Wenn ja welches?
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

überschreib doch den close event:

Code: Alles auswählen

    def closeEvent(self, event):
        tu_was_du_tun_willst()
#        event.ignore()
#falls Du das Event ignorieren wölltest
usingKarmicKoala
User
Beiträge: 27
Registriert: Samstag 28. November 2009, 15:58

Danke für die schnelle Antwort. Wenn ich das in meinem MainWindow mache funktioniert das einwandfrei! Wenn ich allerdings dasselbe in einem Dialog mache klappt es gar nicht.
Ich habe sowohl in der MainWindow-Klasse als auch in der Dialog-Klasse eine Methode

Code: Alles auswählen

def closeEvent(self, event):
  ....
geschrieben. Beim beenden des MainWindows wird die entsprechende Methode aufgerufen, für den Dialog gilt das nicht.
Gibt es da eine plausible Erklärung für ohne, dass ich Quelltext angeben muss, oder braucht ihr was?[
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

Fällt mir so spontan nichts ein woran es liegen könnte.

Ich bräuchte Quellcode...

Gruß
usingKarmicKoala
User
Beiträge: 27
Registriert: Samstag 28. November 2009, 15:58

Hab mal die grobe Grundstruktur aufgeschrieben und alles was imho unnötig war durch "..." ersetzt

Code: Alles auswählen


class chatdialog(QtGui.QDialog, Ui_chatdialog):


#konstruktor des chatfensters
	def __init__(self, parent, chatPartner):
		QtGui.QDialog.__init__(self)
		self.setupUi(self)
		#dem Dialog einen Chatpartner zuordnen
		self.chatPartner = chatPartner
	        #mainwindow zum parent machen
		self.parent = parent
		#liste mit allen sichtbaren labels	
		self.labels = []
		#liste mit ALLEN labels
		self.history = []
		#momentane y-position des lineEdit
		self.currentY = 0

		self.lineEdit.returnPressed.connect(partial(parent.sendMsg, self))

		self.setWindowTitle(self.chatPartner)
		self.show()
		

#ein Label erstellen, es konfigurieren, und an die richtige Stelle setzen
	def createLabel(self, text):
		...

#selbst getippten text ins fenster schreiben und den text zurueckgeben
	def onReturnPressed(self):
		...

#wenn das chatfenster beendet wird
	def closeEvent(self, event):
		#chatpartner aus openWindows löschen
		del self.parent.openWindows[self.chatPartner]
		event.accept()

##----------------------------------------Ende Definition des chat-Fensters-------------------------------------------------------------
#****************************************************************************************************************************************
#****************************************************************************************************************************************
#****************************************************************************************************************************************
#****************************************************************************************************************************************
#-----------------------------------------Anfang Definition des Hauptfensters------------------------------------------------------------



class Dialog(QtGui.QMainWindow, Ui_MainWindow):

#konstruktor des Dialog-Klasse
	def __init__(self):
		QtGui.QMainWindow.__init__(self)
		self.setupUi(self)


		self.socket = QtNetwork.QTcpSocket(self)
		self.socket.connectToHost("192.168.2.104", 6000)	
		
		#liste die den empfangenen text enthaelt
		self.data = []
		#ein dictionary mit den namen des chatpartners als key und das fenster als value
		self.openWindows = {}

		
		#es existiert noch kein chatdialog
		fenster = None

		#empfaenger durch combobox bestimmen; default ist ""
		self.receiver = ""
		
		#ankommende Daten werden in getData verarbeitet
		self.socket.readyRead.connect(self.getData)
		#klick auf den button öffnet ein chatfenster
		self.pushButton.clicked.connect(self.startChat)
		#wird die combobox verändert muss der receiver bestimmt werden
		self.comboBox.currentIndexChanged.connect(self.getReceiver)

#comboBox an die liste der user (data) anpassen
	def fillBox(self, userlist):
	      ...


#die usernamen extrahieren
	def determineNames(self, data):
	    ....


#ankommende Daten verabeiten
	def getData(self): 
		  ...


#chatfenster oeffnen
	def startChat(self):
		fenster = chatdialog(self, self.receiver)
		#den receiver merken um nochmaliges fensteröffnen zu unterbinden
		self.openWindows[self.receiver] = fenster
		chatPartner = fenster.chatPartner
		#fenster ausführen
		fenster.open()


#receiver aus comboBox lesen
	def getReceiver(self):
		...
		

#bei druecken von enter im chatfenster wird die nachricht verschickt
	def sendMsg(self, fenster):
		#nachricht zum verschicken bekommen und createLabel aufrufen
		msg_text = fenster.onReturnPressed()

	
		if msg_text == "EXIT":
			fenster.close()			
		...
		

	def handleDisconnect(self):
		...

	def closeEvent(self, event):
		self.handleDisconnect()
		event.accept()

		
		
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

ich kanns dir nicht richtig erklären warum (evt. macht das lunar ;-) )
aber dein Konstruktoraufruf von

Code: Alles auswählen

class chatdialog(QtGui.QDialog, Ui_chatdialog):


#konstruktor des chatfensters
        def __init__(self, parent, chatPartner):
                QtGui.QDialog.__init__(self)
                self.setupUi(self)
ist das Problem.

Hier mal ein Beispiel wie es tun sollte

Code: Alles auswählen

class chatdialog(QtGui.QDialog, Ui_chatdialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
ich mein aber wenn Du in MainWindow beim Aufruf als parent übergibst dann ist dein chatdialog ein Kind von MainWindow und die events werden an papa MainWindow durchgereicht oder so ähnlich.

Wenn Du zugriff auf MainWindow brauchst übergib es nicht als parent sondern als zusätzlichen Parameter. Aber lass parent=None so wie in meinem kurzen Beispiel.

Wie gesagt so ganz steig ich mit den Vererbungen und den Beziehungen nicht durch, aber da liegt der Hund begraben ...

Gruß
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@usingKarmicKoala:
Warum leitest Du das Chatfenster von einer Dialogklasse ab? Wahrscheinlich liegt das Problem hier begründet. Dialoge zeigen ein etwas anderes Verhalten als "normale" QWidgets.

Vllt. hilft Dir das hier weiter:
http://www.python-forum.de/viewtopic.ph ... 81#p158781
usingKarmicKoala
User
Beiträge: 27
Registriert: Samstag 28. November 2009, 15:58

ja vielleicht wäre QWidget besser?! Aber ein QDialog ist doch sowieso von QWidget abgeleitet oder nicht. das heißt doch, dass auch die events übernommen werden oder seh ich das falsch?

Danke für den Link den guck ich mir mal ganz genau an
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Du öffnest den Dialog mit .open(), ergo ist der Dialog modal --> http://doc.trolltech.com/4.6/qdialog.html#open

Bitte lies die Dokumentation zu QDialog (http://doc.trolltech.com/4.6/qdialog.html), da stehen die Besonderheiten.

Ein Bauchgefühl sagt mir, das Du Dinge wie Rückgabewert, Modalität, shared taskbar entry usw. nicht brauchst. Falls Du gute Gründe für die Benutzung eines Dialoges hast, kannst Du dessen Verhalten auch "zurückbiegen". Ansonsten ist eine Nicht-Dialogklasse sinnvoller.
Antworten