Модальность QMainWindow.Почему Qt :: WindowModal не работает так, как я думал? - PullRequest
0 голосов
/ 22 февраля 2012

Я столкнулся с некоторой проблемой, когда использовал окно Qt и установил модальность окна в WindowModal, очень признателен, если кто-то может помочь мне решить эту проблему

У меня есть окно с именем A, оно является родителем для 3 окон B1, B2 и B3 (они одного класса и генерируются по порядку). Я ожидаю, что любое из этих трех окон будет блокировать А, но они не будут блокировать друг друга.

Согласно документу, я могу сделать это, установив 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

Кто-нибудь может сказать мне, где проблема? Я использовал неправильную модальность? Тем не менее, есть только 3 модальности, а две другие не выглядят так, как мне нужно.

1 Ответ

0 голосов
/ 12 марта 2014

Я тестировал на "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 * m1 или Dialog * m2 до Dialog * m3, он не мигает (эффект мигает), но если я нажму MainWindow до Dialog * m3, окно будет мигать (эффект мигает).

То есть тип модальных окон не блокируется, потому что он ожидает ответа,

то есть, чтобы назвать это:

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

Мне придется подтверждать ответ по одному, потому что он работает в синхронизированном, а не асинхронизированном режиме, иными словами, модальные окна типа предназначены для отправки запроса в родительское окно, поэтому сколько вы не завершайте запрос, все каскадные окна заблокированы. Другими словами, модальные окна (с установленным «родителем») всегда будут ожидать ответа (например, «exec»).

Альтернативное решение:

Вы можете создать блокировку для «окна главного окна», используя setEnable (false), и когда все диалоговые окна закрыты для «окна главного окна», включается с помощью setEnable (true). Смотрите пример:

примечание: если вы будете использовать модальное окно для отправки ответов в родительское окно, в этом примере вам нужно использовать слоты: accept(), reject() или finished(int)

mainwindow.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);
};

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