c++ - Qt: cómo enfocar un QDialog no modal creado desde la ventana principal cuando la ventana principal está bloqueada por un QDialog modal
modal-dialog modeless (2)
En mi aplicación de Qt me enfrento a la siguiente situación: cuando se plantea un evento específico, muestro un QDialog
no modal que solicita al usuario una confirmación. El diálogo se muestra usando la función show()
desde QMainWindow
. Cada vez que se QDialog
evento y no se muestra ningún otro QDialog
modal, el usuario puede hacer clic en el botón de confirmación. Lamentablemente, si un QDialog
modal es visible cuando se produce el evento, el QDialog
no modal QDialog
es accesible. Esto significa que el usuario no puede hacer clic en el botón de confirmación. El siguiente código es una versión simplificada que causa el mismo problema. En este ejemplo, QMainWindow
contiene un botón; cuando se hace clic en el botón, se muestra un QDialog
modal utilizando la función exec()
mientras tanto se ha iniciado un QTimer
. Cada vez que cierro el QDialog
modal antes de que el QTimer
haya transcurrido, el cuadro de diálogo no modal es accesible. Si espero hasta que se muestre el cuadro de diálogo no modal sin cerrar el modal, el cuadro de diálogo no modal es inaccesible (primero necesito cerrar el modal).
Código de MainWindows:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pModeless = new DialogModal(this);
connect(&m_qTimer,SIGNAL(timeout()),this,SLOT(TimerElapsed()));
}
MainWindow::~MainWindow()
{
delete m_pModeless;
delete ui;
}
void MainWindow::TimerElapsed()
{
m_qTimer.stop();
m_pModeless->show();
m_pModeless->activateWindow();
m_pModeless->raise();
m_pModeless->setFocus();
}
void MainWindow::on_pbStartTest_clicked()
{
m_qTimer.start(10000);
DialogModal d(this);
d.exec();
}
Encabezado de MainWindow:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include "dialogmodal.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QTimer m_qTimer;
DialogModal *m_pModeless;
private:
Ui::MainWindow *ui;
private slots:
void TimerElapsed();
void on_pbStartTest_clicked();
};
#endif // MAINWINDOW_H
Encabezado DialogModal:
#ifndef DIALOGMODAL_H
#define DIALOGMODAL_H
#include <QDialog>
namespace Ui {
class DialogModal;
}
class DialogModal : public QDialog
{
Q_OBJECT
public:
explicit DialogModal(QWidget *parent = 0);
~DialogModal();
private slots:
void on_pbExit_clicked();
private:
Ui::DialogModal *ui;
};
#endif // DIALOGMODAL_H
Fuente de DialogModal:
#include "dialogmodal.h"
#include "ui_dialogmodal.h"
DialogModal::DialogModal(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogModal)
{
ui->setupUi(this);
}
DialogModal::~DialogModal()
{
delete ui;
}
void DialogModal::on_pbExit_clicked()
{
close();
}
¿Hay alguna forma de enfocar el diálogo no modal incluso cuando uno o más diálogos modales están presentes?
Cuando se active el cuadro de diálogo modal (a punto de mostrar), puede intentar cambiar el cuadro de diálogo modal del diálogo no modal a este cuadro de diálogo modal. Como el diálogo no modal tendrá el diálogo modal como principal, existe la posibilidad de tenerlo en la parte superior. Aún así, también puede depender de la plataforma.
Por supuesto idealmente para evitar tales situaciones
Encontré una solución de trabajo:
void MainWindow::TimerElapsed()
{
QWidget *pwidget=NULL;
m_qTimer.stop();
foreach(pwidget,QApplication::topLevelWidgets())
{
if ((pwidget->isWindow())&&(pwidget->isModal()))
{
m_pModeless->setParent(pwidget);
}
}
if (pwidget==NULL)
{
m_pModeless->setParent(this);
}
m_pModeless->show();
m_pModeless->activateWindow();
m_pModeless->raise();
m_pModeless->setFocus();
}