2013-01-16 23 views
23

Utilizzo di Qt Creare una QMainWindow e si desidera richiamare una funzione DOPO che viene visualizzata la finestra. Quando chiamo la funzione nel costruttore la funzione (in effetti una finestra di dialogo) viene chiamata prima che venga visualizzata la finestra.Come chiamare la funzione dopo che viene visualizzata la finestra?

+0

Chiama 'QMainWindow :: show()' e quindi 'QMetaObject :: invokeMethod()' e fai ciò che vuoi anche fare. – Trilarion

risposta

21

Se si vuole fare qualcosa, mentre il widget è reso visibile, è possibile ignorare QWidget::showEvent in questo modo:

class YourWidget : public QWidget { ... 

void YourWidget::showEvent(QShowEvent* event) { 
    QWidget::showEvent(event); 
    //your code here 
} 
+2

Ho già pensato di implementare la mia funzione show, ma non mi è mai venuto in mente che potrei chiamare la funzione show dei genitori PRIMA del mio codice.* facepalm * – HWende

+1

In realtà, in questo caso, non fa differenza dove si chiama QWidget :: showEvent(), perché l'implementazione di QWidget :: showEvent() è vuota e non fa nulla. (Questo è ovviamente un dettaglio di implementazione su cui non si dovrebbe fare affidamento). –

+6

Sono andato a quattro l'implementazione suggerita ma la finestra di dialogo è ancora mostrata PRIMA che venga visualizzata la finestra. – HWende

11

provare questo:

in mainwindow.h:

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

protected: 
     void showEvent(QShowEvent *ev); 

signals: 
     void sigShowEvent(); 

private slots: 
     void slotShowEvent(); 
} 

in mainwindow.cpp:

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    connect(this, SIGNAL(sigShowEvent()), this, SLOT(slotShowEvent())); 
} 


void MainWindow::showEvent(QShowEvent *ev) 
{ 
    QMainWindow::showEvent(ev); 
    emit sigShowEvent(); 
} 

void MainWindow::slotShowEvent() 
{ 
    // your code placed here 
} 
esempio
+0

Parentesi mancanti, dovrebbe essere 'connect (questo, SIGNAL (window_loaded()), this, SLOT (your_function()));' – vsz

+1

@vsz editted, grazie –

+1

Incredibile ma divertente allo stesso tempo, perché usare questo segnale e uno slot extra. Richiama la funzione (ad esempio * doWork() *) direttamente all'interno del void MainWindow :: showEvent(). –

11

Segui Reza di Ebrahimi, ma tenere a mente:

Non omettere il quinto parametro della connect() funzione che specifica il tipo di connessione; assicurati che sia QueuedConnection.

cioè

connect(this, SIGNAL(window_loaded), this, SLOT(your_function()), Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection)); 

credo che si sarebbe ottenere quello che vi serve se lo si fa in questo modo.

  • Ci sono diversi tipi di connessioni segnale slot: AutoConnection, DirectConnection, QueuedConnection, BlockingQueuedConnection (+ opzionale UniqueConnection). Leggi il manuale per i dettagli. :)
1

Ho trovato una bella risposta in this question che funziona bene, anche se si utilizza una funzione Sleep().

Quindi provato questo:

//- cpp-file ---------------------------------------- 

#include "myapp.h" 
#include <time.h> 
#include <iosteream> 

MyApp::MyApp(QWidget *parent) 
    : QMainWindow(parent, Qt::FramelessWindowHint) 
{ 
    ui.setupUi(this); 
} 

MyApp::~MyApp() 
{ 

} 

void MyApp::showEvent(QShowEvent *event) { 
    QMainWindow::showEvent(event); 
    QTimer::singleShot(50, this, SLOT(window_shown())); 
    return; 
} 

void MyApp::window_shown() { 
    std::cout << "Running" << std::endl; 
    Sleep(10000); 
    std::cout << "Delayed" << std::endl; 
    return; 
} 

//- h-file ---------------------------------------- 

#ifndef MYAPP_H 
#define MYAPP_H 

#include <QtWidgets/QMainWindow> 
#include <qtimer.h> 
#include <time.h> 
#include "ui_myapp.h" 


class MyApp : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    MyApp(QWidget *parent = 0); 
    ~MyApp(); 

protected: 
    void showEvent(QShowEvent *event); 


private slots: 
    void window_shown(); 

private: 
    Ui::MyAppClass ui; 
}; 

#endif // MYAPP_H 
0

ho risolto senza un timer utilizzando evento Paint. Funziona per me almeno su Windows.

// MainWindow.h 
class MainWindow : public QMainWindow 
{ 
    ... 
    bool event(QEvent *event) override; 
    void functionAfterShown(); 
    ... 
    bool functionAfterShownCalled = false; 
    ... 
} 

// MainWindow.cpp 
bool MainWindow::event(QEvent *event) 
{ 
    const bool ret_val = QMainWindow::event(event); 
    if(!functionAfterShownCalled && event->type() == QEvent::Paint) 
    { 
     functionAfterShown(); 
     functionAfterShownCalled = true; 
    } 
    return ret_val; 
} 
0

metodo reimplementare void show() come questo:

void MainWindow::show() 
{ 
    QMainWindow::show(); 
    // Call your special function here. 
} 
+0

Solo un promemoria amichevole per chiunque intorno: 'QWidget :: show()' non è virtuale, e quindi il tentativo di chiamare tale metodo "reimplementato" su un puntatore upcast fallirà inevitabilmente. – user35443

0

La soluzione migliore per me è il conteggio una volta vernice evento:

.H

public: 
void paintEvent(QPaintEvent *event); 

cpp

#include "qpainter.h" 
#include <QMessageBox> // example 

int contPaintEvent= 0; 

void Form2::paintEvent(QPaintEvent* event) 
{ 
    if (contPaintEvent ==0) 
    { 
    QPainter painter(this); 
    QMessageBox::information(this, "title", "1 event paint"); // example 
    // actions 
    contPaintEvent++; 
    } 
} 
Problemi correlati