2010-06-10 37 views
10

esto puede parecer una pregunta muy simple, pero quiero volcar algunos datos cada vez que el QMainWindow cierra, por lo que se utiliza el siguiente fragmento de código:Qt QMainWindow en Cerrar

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

Pero esto no parece para hacer que llame al close(). ¿Estoy haciendo esto mal?
¿No se supone que la unidad central debe ser destruida?

O tal vez la aplicación se cierra antes de llamar al close() ?.

¿Alguna otra forma de hacerlo?

+0

¿Dónde encaja 'this' dentro de la jerarquía' QObject'? Puede ser que se borre antes de que se envíe la señal. Por supuesto, no me preocuparía demasiado ya que hay mejores alternativas en las respuestas dadas hasta ahora. – Troubadour

+0

No puede volcar datos con el código que ha mostrado ... ¿También si su pregunta es cómo volcar datos antes de que se cierre QMainWindow? o por qué QMainwindow no se está cerrando? Deje en claro ... – liaK

+1

Quiero escribir un archivo XML después de hacer clic en la 'x' para cerrar la ventana principal. Parece que no funciona con el código anterior o QApplication :: lastWindowClosed() (o QApplication :: aboutToQuit()) ... Havent probó QCloseEvent, pero para mantener la estructura MVC, prefiero no hacerlo. La clase en la que estoy trabajando no es la QMainWindow, sino que utilizo los archivos obtenidos al compilar los archivos de la interfaz de usuario creados en el diseñador. – Cenoc

Respuesta

10

Yo probaría en su lugar.

+0

¿No funcionó, debe significar que está siendo destruido antes de que la señal pueda ser aceptada? Pero eso es extraño porque el destructor de la clase no parece estar produciendo nada (a través de std :: cerr) – Cenoc

+0

Asegúrese de que el objeto con la ranura no sea un elemento secundario de QMainWindow. Los QWidgets destruyen a todos sus hijos cuando caen. –

+0

@Cenoc: publique su función 'main', puede ayudar a aclarar lo que está sucediendo. –

4

¿Podría implementar la función closeEvent para su QMainWindow y poner allí su código?

1

Su pregunta inicial y el código no coinciden. Si desea hacer algo en el QMainWindow, cree una subclase y vuelva a implementar closeEvent o conéctese al MainWindow::destroyed(). Sin embargo, vea el tercer párrafo para una nota.

Pero su código muestra lo que parece ser una 3ra clase que está conectando a un hijo del MainWindow que se está destruyendo en un espacio llamado close(). centralwidget se destruirá DESPUÉS de que MainWindow ya esté destruido, por lo que es probable que esto no te ayude de todos modos.

Además, esto depende de cómo haya creado MainWindow (pila o pila) y si lo está destruyendo correctamente. Idealmente, debería crear una subclase de QMainWindow (que si usó el diseñador probablemente ya tenga).

22

Es mejor para volver a poner en práctica una función virtual en su clase principal MainWindow así:

class MainWindow : public QMainWindow { 

    Q_OBJECT; 

public: 
    MainWindow(); 

protected: 
    void closeEvent(QCloseEvent *event); 
} 

y luego declarar en el archivo fuente:

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

Buena suerte.

+2

Es una buena idea completar la anulación. IE: en closeEvent() llama a QMainWindow :: closeEvent (evento); al final de la función. Vea el ejemplo en la documentación para la función saveState() aquí: http://doc.qt.io/qt-4.8/qmainwindow.html – Ph0t0n

+0

Si bien Ph0t0n no es necesariamente incorrecto, las implementaciones 'closeEvent()' en el mundo real típicamente llama a 'event.accept()' o 'event.ignore()' dependiendo de si existen cambios no guardados o no. 'QMainWindow :: closeEvent (event)' normalmente se llama * no *. Consulte ['closeEvent()' documentation] (http://doc.qt.io/archives/qt-4.8/qwidget.html#closeEvent) para obtener otro ejemplo útil. –

-1

¿Qué le parece agregar el código de volcado al destructor de su ventana principal?

+0

Probé eso, no emite ... ¿extraño? – Cenoc

+0

No puede acceder a la E/S en destruido o al destructor de MainWindow: finalmente está en su destructor de aplicaciones y todo se destruye. Use closeEvent() en su lugar. – Jens

1

Implemente QMainWindow::closeEvent(QCloseEvent *) en su clase. A continuación, implemente una nueva señal llamada closing() y emítela desde su implementación de QMainWindow::closeEvent(). Luego puede conectarse a esa señal para hacer algo justo antes de que se cierre la ventana. También puede usar closeEvent directamente para hacer lo que necesita hacer, como guardar estado, sincronizar datos o lo que sea.

1

enter image description here En Python (o PyQt4 pyqt5) que tendría que hacer lo siguiente:

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... 
     # 

    '''''' 

Es interesante saber que las cosas en el CloseEvent (..) función es ejecutada solo antes de   la ventana se cierra.Esto se puede comprobar en la siguiente prueba:

# 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())) 

    '''''' 

Ésta es la salida en su terminal:

<myProj.MyWindow object at 0x000001D3C3B3AAF8> 
True 

<myProj.MyWindow object at 0x000001D3C3B3AAF8> 
False 

Esto demuestra que la ventana era todavía visible al entrar en el CloseEvent (..) función , pero no después de salir de esa función.

Cuestiones relacionadas