I have a MainWindow with a non-modal QDialog and a QPushButton just for the purpose of showing the dialog. When the application is minimised and maximised again, I want the dialog, if visible, to regain keyboard focus.
Here is the code:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
QDialog *dialog;
public:
explicit MainWindow(QWidget *parent = nullptr);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QPushButton>
#include <QDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
dialog(new QDialog(this))
{
QPushButton *button = new QPushButton("show dialog", this);
connect(button, &QPushButton::clicked, dialog, &QDialog::show);
setCentralWidget(button);
}
Sounds very simple but I have tried various approaches without any luck:
Approach 1: Listen to QApplication::applicationStateChanged() signal and set focus to dialog when application state becomes active.
Approach 2: Listen to dialog's show and window activate events and setting focus when triggered.
Approach 3: Listen to main window's show and window activate events and setting focus when triggered.
Here is the code with the above approaches implemented:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
QDialog *dialog;
public:
explicit MainWindow(QWidget *parent = nullptr);
virtual bool event(QEvent *event) override;
virtual bool eventFilter(QObject *watched, QEvent *event) override;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QPushButton>
#include <QDialog>
#include <QEvent>
#include <QApplication>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
dialog(new QDialog(this))
{
QPushButton *button = new QPushButton("show dialog", this);
connect(button, &QPushButton::clicked, dialog, &QDialog::show);
setCentralWidget(button);
dialog->installEventFilter(this);
//set focus on dialog when app becomes active
connect(qApp, &QApplication::applicationStateChanged, this, [this](Qt::ApplicationState state){
if (dialog->isVisible() && state == Qt::ApplicationActive) {
dialog->setFocus();
}
});
}
bool MainWindow::event(QEvent *event)
{
//set focus on dialog when main window is shown or activated
if (event->type() == QEvent::Show || event->type() == QEvent::WindowActivate) {
if (dialog->isVisible()) {
dialog->setFocus();
}
}
return QMainWindow::event(event);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
//set focus on dialog when dialog is shown or activated
if (watched == dialog) {
if (event->type() == QEvent::Show || event->type() == QEvent::WindowActivate) {
dialog->setFocus();
}
}
return QMainWindow::eventFilter(watched, event);
}