web-dev-qa-db-fra.com

Comment appeler fonction après que la fenêtre soit affichée?

Utilisation de Qt Je crée un QMainWindow et souhaite appeler une fonction APRÈS que la fenêtre s’affiche. Lorsque j'appelle la fonction dans le constructeur, la fonction (un dialogue en fait) est appelée avant que la fenêtre ne soit affichée.

29
HWende

Si vous voulez faire quelque chose pendant que le widget est rendu visible, vous pouvez remplacer QWidget :: showEvent comme ceci:

class YourWidget : public QWidget { ...

void YourWidget::showEvent( QShowEvent* event ) {
    QWidget::showEvent( event );
    //your code here
} 
31
Frank Osterfeld

Suivez l'exemple de Reza Ebrahimi, mais gardez cela à l'esprit:

N'omettez pas le cinquième paramètre de la fonction connect() qui spécifie le type de connexion; assurez-vous qu'il soit QueuedConnection.

C'EST À DIRE., 

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

Je crois que vous obtiendriez ce dont vous avez besoin si vous le faisiez de cette façon.

  • Il existe plusieurs types dans les connexions d'emplacement de signal: AutoConnection, DirectConnection, QueuedConnection, BlockingQueuedConnection (+ optionnel UniqueConnection) Lisez le manuel pour plus de détails. :)
13
Kieung Kim

essaye ça:

dans mainwindow.h:

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

protected:
      void showEvent(QShowEvent *ev);

private:
      void showEventHelper();
      Ui::MainWindow *ui;
}

dans mainwindow.cpp:

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

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

void MainWindow::showEventHelper()
{
    // your code placed here
}
12
Reza Ebrahimi

Je l'ai résolu sans minuterie en utilisant l'événement Paint. Fonctionne pour moi au moins sur 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;
}
1
RuslanK

La meilleure solution pour moi est de compter une fois l'événement Paint:

.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++;
  }
}
1
hexadecimal

J'ai trouvé une bonne réponse dans cette question qui fonctionne bien, même si vous utilisez une fonction Sleep ().

Alors essayé ceci:

//- 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
1
Michael Sasser

En supposant que vous souhaitiez exécuter votre code dans le fil de l'interface utilisateur de la fenêtre après / la fenêtre a été affichée, vous pouvez utiliser le code relativement compact suivant. 

class MainWindow : public QMainWindow
{
        // constructors etc omitted.

protected:
    void showEvent(QShowEvent *ev)
    {
        QMainWindow::showEvent(ev);
        // Call slot via queued connection so it's called from the UI thread after this method has returned and the window has been shown
        QMetaObject::invokeMethod(this, "afterWindowShown", Qt::ConnectionType::QueuedConnection);
    }

private slots:
    void afterWindowShown()
    {
        // your code here
        // note this code will also be called every time the window is restored from a minimized state
    }
};

Il invoque afterWindowShown par son nom, mais ce genre de chose est assez courant dans Qt. Il existe des moyens d'éviter cela, mais ils sont un peu plus verbeux.

Notez que ce code devrait fonctionner pour toute classe dérivée de QWidget, pas seulement pour les classes dérivées de QMainWindow.

En théorie, il pourrait être possible pour un utilisateur très rapide d'appeler une sorte d'action sur l'interface utilisateur de la fenêtre affichée avant que l'option afterWindowShown puisse être appelée, mais cela semble peu probable. Quelque chose à garder à l’esprit et à coder de façon défensive peut-être.

0
persiflage

Méthode de réimplémentation void show() comme ceci:

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