2013-04-04 3 views
7

Come esempio molto semplice, voglio mostrare una finestra di dialogo in Qt quando preme un pulsante. Il modello di solito per questo (nell'applicazione Attualmente sto lavorando su) sembra essere il seguente:Come mostrare una finestra in Qt e cancellarla non appena viene chiusa?

class MainWindow { 
    ... 
private slots: 
    buttonClicked(); 
    ... 
private: 
    ChildWindow * childWindow; 
} 

MainWindow::MainWindow(QWidget * parent) : QWidget(parent) { 
    ... 
    childWindow = new ChildWindow(this); 
    ... 
} 

MainWindow::buttonClicked() { 
    childWindow.show(); 
} 

Venendo da Form .NET e Windows (e perché non ho bisogno di accesso a tale oggetto da altrove nella classe) il seguente schema è più familiare per me:

button1_Clicked(object sender, EventArgs e) { 
    ChildWindow f = new ChildWindow(); 
    f.Show(); 
} 

la variabile locale significa che non ho ancora un altro campo di istanza e anche che la finestra non indugiare in giro nella memoria per molto più a lungo del necessario . Una traduzione diretta di questo in C++ sarebbe un po 'brutta perché nessuno si sarebbe chiarito in seguito. Ho provato le seguenti cose:

  1. shared_ptr. Non c'è fortuna, la finestra è delete d non appena termina il metodo, il che significa che la nuova finestra appare per una frazione di secondo e scompare di nuovo. Non così buono.

  2. exec() anziché show(). Ciò funzionerebbe per le finestre di dialogo modali, ma la documentazione sembrava implicare che interrompesse anche il ciclo degli eventi e che dovresti chiamare regolarmente QApplication::processEvents() se deve ancora essere aggiornato. Capisco abbastanza poco qui, ma immagino che non sia neanche troppo bello.

  3. deleteLater(). Purtroppo, solo mostrare una finestra non blocca deleteLater in modo che svanisca non appena appare.

C'è una buona opzione per pulire appena dopo la finestra quando la chiudo?

risposta

12
childWindow->setAttribute(Qt::WA_DeleteOnClose); 

noti inoltre che la chiamata exec() bloccherà esecuzione del ciclo di eventi chiamata, ma sarà generare un proprio ciclo di eventi, così chiamate per processEvents() dovrebbe essere necessario.

+0

Non riuscivo a trovare quel consiglio per 'exec' di nuovo ovunque nei documenti, poteva essere che fosse solo su qualche blog casuale di valore dubbio. E grazie per l'attributo. Ho cercato almeno un'ora (+ tempo di costruzione per gli esperimenti) fino a quando non sono incappato nell'idea di collegare solo il segnale "finito" (che non era ottimale ma sufficiente per il mio scopo). – Joey

+0

In realtà è documentato abbastanza chiaramente in questo file .cpp http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/dialogs/qdialog.cpp#line562;) – Chris

+0

Mi riferivo a ciò che ho scritto nella domanda riguardante 'processEvents'. Quel 'exec' ferma il ciclo degli eventi genitore è abbastanza ovvio, perché sta bloccando; anche che deve crearne uno nuovo per la finestra di dialogo. – Joey

2

È possibile collegare il segnale finished() di dialogo th alla sua deleteLater Slot:

ChildWindow * d = new ChildWindow(this); 
connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater())); 
d->show(); 

questo modo sarà delete d non appena si chiude la finestra di dialogo.

+0

Nota: questo funziona nel caso in cui non sia necessario alcun risultato di dialogo. Se hai ancora bisogno dell'argomento da 'finished()' allora non so cosa succede. Ma per il mio problema qui è stato abbastanza. – Joey

Problemi correlati