Qt: How to give focus to a modeless QDialog created from the main window when the main window is blocked by a modal QDialog

孤人 提交于 2019-12-01 05:54:53

问题


In my Qt Application I'm facing the following scenario: When a specific event is raised I show a modeless QDialog which asks the user for a confirmation. The Dialog is showed using show() function from a QMainWindow. Anytime the event is raised and no other modal QDialog are shown, the user is able to click the confirmation button. Unfortunately if a modal QDialog is visible when the event is raised, the modeless QDialog is unaccessible. This means that the user cannot click the confirmation button. The following code is a simplified version that causes the same problem In this example the QMainWindow contains a button, when the button is clicked a modal QDialog is shown using the exec() function in the meanwhile a QTimer has been started. Anytime I close the modal QDialog before the QTimer is elapsed the modeless dialog is accesible. If I wait until the modeless dialog is shown without closing the modal one, the modeless dialog is inaccessible (I need to close the modal one first).

MainWindows code:

#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();
}

MainWindow Header:

#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

DialogModal Header:

#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

DialogModal source:

#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();
}

Is there anyway to give focus to the modeless dialog even when one or more modal dialog are present?


回答1:


I found a working solution:

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();
}



回答2:


When modal dialog to be activated (about to show) you may try change parent of modeless dialog to this modal dialog. As modeless dialog will have the modal dialog as parent then there is a chance to have it on top. Still it may also depend on platform.

Of course ideally to avoid such situations



来源:https://stackoverflow.com/questions/21609481/qt-how-to-give-focus-to-a-modeless-qdialog-created-from-the-main-window-when-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!