0

我在使用 Qt 窗口并将窗口模式设置为 WindowModal 时遇到了一些问题,如果有人可以帮助我解决这个问题,我真的很感激

我有一个名为 A 的窗口,它是 3 个窗口 B1、B2 和 B3 的父级(它们是同一类并按顺序生成)。我期望的是这三个窗口中的任何一个都会阻止 A,但它们不会相互阻止。

根据文档,我可以通过将 B1、B2 和 B3 设置为 Qt::WindowModal 来做到这一点。 http://developer.qt.nokia.com/doc/qt-4.8/qt.html#WindowModality-enum

但是结果是B1、B2、B3都阻塞了A,还好,但是B1被B2阻塞了,B2又被B3阻塞了,和我想象的不一样。它变成一个订单(A < B1 < B2 < B3)。

谁能告诉我问题出在哪里?我使用了错误的方式吗?但是,只有 3 种模式,另外两种看起来不像我需要的。

4

1 回答 1

0

我在“windows7”上测试过,代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    Dialog *m1 = new Dialog(this);
    Dialog *m2 = new Dialog(this);
    Dialog *m3 = new Dialog(this);

    m1->setWindowModality(Qt::WindowModal);
    m1->setWindowTitle(tr("Window 1"));

    m2->setWindowModality(Qt::WindowModal);
    m2->setWindowTitle(tr("Window 2"));

    m3->setWindowModality(Qt::WindowModal);
    m3->setWindowTitle(tr("Window 3"));

    m1->show();
    m2->show();
    m3->show();
}

MainWindow::~MainWindow()
{
    delete ui;
}

唯一可以点击的窗口是Dialog * m3,另一个被屏蔽了,但是当你点击MainWindow的时候你可能会注意到效果不同。

如果单击Dialog * m1Dialog * m2Dialog * m3窗口不会 BLINK(效果闪烁),但如果我单击MainWindowDialog * m3窗口会 BLINK(效果闪烁)。

那就是模式窗口不会阻塞的类型,因为它正在等待响应,

即称它为:

    Dialog *m1 = new Dialog(this);
    Dialog *m2 = new Dialog(this);
    Dialog *m3 = new Dialog(this);

我必须一次确认一个响应,因为它工作在同步而不是异步模式下,换句话说,Modal 类型的窗口旨在向父窗口发送请求,所以你没有完成多少请求所有级联窗口都被阻止。换句话说,windows modal(设置了“parent”)将始终期待响应(如“exec”)。

替代解决方案:

您可以使用为“MainWindow 窗口”创建一个锁,setEnable (false)并且当所有对话框都关闭到“MainWindow 窗口”时,使用setEnable (true). 参见示例:

注意:如果您将使用模态窗口向父窗口提交响应,在此示例中您需要使用 SLOTS accept():reject()finished(int)

主窗口.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

public slots:
    void showChilds();
    void findDialogs(const int a = -1);
};

主窗口.cpp

#include "dialog.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(showChilds()));
}

void MainWindow::showChilds() {
    setEnabled(false);

    Dialog *m1 = new Dialog(this);
    Dialog *m2 = new Dialog(this);
    Dialog *m3 = new Dialog(this);

    m1->setAttribute(Qt::WA_DeleteOnClose, true);
    m2->setAttribute(Qt::WA_DeleteOnClose, true);
    m3->setAttribute(Qt::WA_DeleteOnClose, true);

    m1->setWindowTitle("1");
    m2->setWindowTitle("2");
    m3->setWindowTitle("3");

    m1->show();
    m2->show();
    m3->show();

    QObject::connect(m1, SIGNAL(finished(int)), this, SLOT(findDialogs(int)));
    QObject::connect(m2, SIGNAL(finished(int)), this, SLOT(findDialogs(int)));
    QObject::connect(m3, SIGNAL(finished(int)), this, SLOT(findDialogs(int)));
}

void MainWindow::findDialogs(const int a)
{
    if(a==-1){
        QObject *tmp;
        QObjectList list = this->children();
        const int j = list.length();
        for(int i=0; i < j; i++) {
            tmp = (QObject *) (list.at(i));
            if(tmp!=0 && tmp->objectName()=="Dialog") {
                return;
            }
        }

        setEnabled(true);
    } else {
        QTimer::singleShot(1, this, SLOT(findDialogs()));
    }
}
于 2014-03-11T21:59:57.980 回答