2010-06-10 14 views
10

questo può sembrare una domanda molto semplice, ma voglio fare uscire alcuni dati ogni volta che la QMainWindow chiude, così ho usato il seguente pezzo di codice:Qt QMainWindow a chiudere

QObject::connect(MainWindow.centralwidget, SIGNAL(destroyed()), this, SLOT(close())); 

Ma questo non sembra per chiamare il numero close(). Sto sbagliando ?.
Supponiamo che l'iniziativa centrale non sia distrutta ?.

O forse l'applicazione si chiude prima che sia possibile chiamare close() ?.

Altri modi per farlo?

+0

Dove si trova "questo" nella gerarchia di 'QObject'? Potrebbe essere che viene cancellato prima che il segnale venga inviato. Ovviamente non mi preoccuperei troppo perché ci sono alternative migliori nelle risposte date finora. – Troubadour

+0

Non puoi scaricare i dati con il codice che hai mostrato ... Inoltre, se la tua domanda è come scaricare i dati prima che QMainWindow si chiuda? o perché QMainwindow non si sta chiudendo? Chiaro ... – liaK

+1

Voglio scrivere e file XML dopo aver fatto clic sulla 'x' per chiudere la finestra principale. Non sembra funzionare con il codice sopra o QApplication :: lastWindowClosed() (o QApplication :: aboutToQuit() per l'argomento) ... Havent ha provato QCloseEvent, ma per mantenere la struttura MVC, io invece no. La classe in cui sto lavorando non è la QMainWindow, piuttosto utilizzo i file ottenuti compilando i file ui creati nel designer. – Cenoc

risposta

10

Mi piacerebbe provare invece.

+0

Non ha funzionato, deve significare che viene distrutto prima che il segnale possa essere accettato? Ma è strano perché il distruttore della classe non sembra emettere nulla (tramite std :: cerr) – Cenoc

+0

Assicurati che l'oggetto con lo slot non sia figlio di QMainWindow. QWidgets distrugge tutti i loro figli quando cadono. –

+0

@Cenoc: Pubblica la tua funzione 'main', può aiutare a chiarire cosa sta succedendo. –

4

È possibile implementare la funzione closeEvent per il proprio QMainWindow e inserire il proprio codice?

1

La tua domanda iniziale e il codice non corrispondono. Se vuoi fare qualcosa su QMainWindow o creare una sottoclasse e re-implementare closeEvent o connettersi a MainWindow::destroyed(). Vedi comunque il 3 ° paragrafo per una nota.

Tuttavia, il codice mostra ciò che sembra essere una terza classe che sta connettendo un figlio di MainWindow in una posizione denominata close(). centralwidget verrà distrutto DOPO che MainWindow è già stato distrutto, quindi probabilmente non ti sarà d'aiuto.

Inoltre, questo dipende da come è stato creato MainWindow (stack o heap) e se lo si sta distruggendo correttamente. Idealmente, dovresti creare una sottoclasse di QMainWindow (che probabilmente hai già utilizzato il designer).

22

È meglio ri implementare una funzione virtuale nel vostro principale MainWindow classe come questa:

class MainWindow : public QMainWindow { 

    Q_OBJECT; 

public: 
    MainWindow(); 

protected: 
    void closeEvent(QCloseEvent *event); 
} 

e quindi dichiarare nel file sorgente:

void MainWindow::closeEvent(QCloseEvent *event) { 
    // do some data saves or something else 
} 

Buona fortuna.

+2

È consigliabile completare l'override. IE: in closeEvent() chiama QMainWindow :: closeEvent (evento); alla fine della funzione. Vedere l'esempio nella documentazione per la funzione saveState() qui: http://doc.qt.io/qt-4.8/qmainwindow.html – Ph0t0n

+0

Mentre Ph0t0n non è necessariamente sbagliato, le implementazioni real-world 'closeEvent()' chiama "event.accept()" o "event.ignore()" a seconda che esistano o meno modifiche non salvate. 'QMainWindow :: closeEvent (event)' è in genere * non * chiamato. Vedi ['closeEvent()' documentation] (http://doc.qt.io/archives/qt-4.8/qwidget.html#closeEvent) per un altro esempio utile. –

-1

Come aggiungere il codice di dump al distruttore della finestra principale?

+0

Ho provato che non emette .... strano? – Cenoc

+0

Non è possibile accedere a I/O in distrutto o al distruttore di MainWindow: si è finalmente nel distruttore delle applicazioni e tutto viene distrutto. Utilizzare invece closeEvent(). – Jens

1

Implementare QMainWindow::closeEvent(QCloseEvent *) nella classe. Quindi implementare un nuovo segnale chiamato closing() ed emetterlo dall'implementazione di QMainWindow::closeEvent(). Quindi è possibile connettersi a quel segnale per fare qualcosa subito prima che la finestra venga chiusa. Puoi anche usare direttamente closeEvent per fare ciò che devi fare, come salvare lo stato, sincronizzare i dati o qualsiasi altra cosa.

1

enter image description here In Python (PyQt4 o pyqt5) si avrebbe bisogno di fare quanto segue:

class MyWindow(QMainWindow): 
    def __init__(self): 
     super(MyWindow, self).__init__() 
     # 
     # My initializations... 
     # 

    '''''' 

    def closeEvent(self, *args, **kwargs): 
     # 
     # Stuff I want to do when this 
     # just before (!) this window gets closed... 
     # 

    '''''' 

E 'interessante sapere che la roba in CloseEvent (..) funzione viene eseguito solo prima di   la finestra si chiude.Lo si può verificare con il seguente test:

# Test if the closeEvent(..) function 
    # executes just before or just after the window closes. 
    def closeEvent(self, *args, **kwargs): 
     # 'self' is the QMainWindow-object. 
     print(self) 
     print(self.isVisible()) 

     # Print out the same stuff 2 seconds from now. 
     QTimer.singleShot(2000, lambda: print(self)) 
     QTimer.singleShot(2100, lambda: print(self.isVisible())) 

    '''''' 

Questa è l'uscita nel vostro terminale:

<myProj.MyWindow object at 0x000001D3C3B3AAF8> 
True 

<myProj.MyWindow object at 0x000001D3C3B3AAF8> 
False 

Ciò dimostra che la finestra era ancora visibile quando si entra nel CloseEvent (..) funzione , ma non dopo aver abbandonato quella funzione.

Problemi correlati