【问题标题】:Qt: How to give focus to a modeless QDialog created from the main window when the main window is blocked by a modal QDialogQt:当主窗口被模态QDialog阻塞时,如何将焦点放在从主窗口创建的无模态QDialog上
【发布时间】:2014-02-06 17:10:09
【问题描述】:

在我的 Qt 应用程序中,我面临以下情况: 当引发特定事件时,我会显示一个无模式的QDialog,它要求用户确认。 使用QMainWindow 中的show() 函数显示对话框。 每当引发事件并且没有显示其他模式 QDialog 时,用户都可以单击确认按钮。 不幸的是,如果在引发事件时可以看到模态 QDialog,则无法访问非模态 QDialog。这意味着用户不能点击确认按钮。 以下代码是导致相同问题的简化版本 在此示例中,QMainWindow 包含一个按钮,当单击该按钮时,使用exec() 函数显示模态QDialog,同时已启动QTimer。 每当我在QTimer 过去之前关闭模式QDialog 时,就可以访问无模式对话框。如果我等到显示无模式对话框而不关闭模式对话框,则无法访问无模式对话框(我需要先关闭模式对话框)。

主窗口代码:

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

主窗口标题:

#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 标题:

#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 来源:

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

即使存在一个或多个模式对话框,是否仍将焦点放在无模式对话框上?

【问题讨论】:

    标签: c++ qt modal-dialog qdialog modeless


    【解决方案1】:

    我找到了一个可行的解决方案:

    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】:

      当模态对话框被激活(即将显示)时,您可以尝试将无模式对话框的父级更改为此模态对话框。由于无模式对话框将以模式对话框作为父级,因此有机会将其置于顶部。不过它也可能取决于平台。

      当然最好避免这种情况

      【讨论】:

      • MainWindow 中我可以做到这一点,但是如果模态对话框打开另一个模态对话框怎么办?有什么办法可以得到顶部模态对话框的指针?
      • topLevelWidget() 或 window() 应该返回这个顶级小部件指针
      • 是的,谢谢,我今天早上找到了,现在我的问题是集合QApplication::topLevelWidgets() 在我调用isWindow 函数时返回多个小部件来回答true。我会尝试将isWindowisModal 组合在一起,看看会发生什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多