QMainWindow 的模式。为什么 Qt::WindowModal 不像我想象的那样工作?

发布于 2025-01-08 04:53:52 字数 535 浏览 3 评论 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 种模式,另外两种看起来不像我需要的。

I met some problem when using Qt window and set window modality to WindowModal, really appreciate if someone can help me solving this problem

I have a window called A, it's parent of 3 windows B1, B2, and B3 (they are same class and generated in order).
What I expect is that any of these three windows will block A, but they won't block each other.

According to the document, I can do this by setting B1, B2, and B3 to Qt::WindowModal.
http://developer.qt.nokia.com/doc/qt-4.8/qt.html#WindowModality-enum

However, the result is that All of B1, B2, B3 will block A, which is fine, but B1 is blocked by B2, and B2 is blocked by B3, which is not as what I expect.
It becomes an order (A < B1 < B2 < B3).

Anyone can tell me where's the problem ? Did I use the wrong modality? However, there're only 3 modality, and other two doesn't look like what I need.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

太傻旳人生 2025-01-15 04:53:52

我在“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 窗口将会闪烁(效果闪烁)。

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

即调用它:

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

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

替代解决方案:

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

注意:如果您将使用模态窗口向父窗口提交响应,则在此示例中您需要使用 SLOTS:accept()reject()完成(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()));
    }
}

I tested on a "windows7", follows the code:

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

The only window that can be clicked is the Dialog * m3, the other is blocked, but when you click MainWindow you may notice that the effect is different.

If you click the Dialog * m1 or Dialog * m2 to Dialog * m3 window does not BLINK (effect blink),
but if I click MainWindow to Dialog * m3 window will BLINK (effect blink).

That is the type modal windows do not block because it is waiting for a response,

ie to call it:

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

I'll have to confirm the response one at a time, because it works in a synchronized and not asynchronized mode, in other words, the type Modal windows are intended to send a request to the parent window, so how much you do not complete the request all cascade windows are blocked. In other words, windows modal (with "parent" setted), will always expect an response (like the "exec").

Alternative solution:

You can create a lock for "MainWindow window" using setEnable (false) and when all dialogs are closed to "MainWindow window" is enabled with setEnable (true). See example:

note: if you will use a modal window to submit responses to the parent window, in this example you need to use the SLOTS: accept(), reject() or 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()));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文