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.
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
}
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.
AutoConnection
, DirectConnection
, QueuedConnection
, BlockingQueuedConnection
(+ optionnel UniqueConnection
) Lisez le manuel pour plus de détails. :)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
}
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;
}
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++;
}
}
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
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.
Méthode de réimplémentation void show()
comme ceci:
void MainWindow::show()
{
QMainWindow::show();
// Call your special function here.
}