Qt中的模态、非模态、半模态对话框

1. 模态对话框(Modal)

模态对话框 是指在同一个应用程序中,阻塞其他可见窗口输入的对话框。一般用于用户输入文件名或用于应用程序的配置选项。可以分为应用模态和窗口模态。

下面是一个模态对话框的显示效果:

对话框的完整代码如下:

头文件:

class ModalDialog : public QDialog
{
    Q_OBJECT
public:
    ModalDialog(QWidget* parent = nullptr);
    ~ModalDialog();

    void setContentText(const QString& text);

signals:
    void clickedOKButton(void);
    void clickedCannelButton(void);

private:
    QLabel* m_pContentLabel = nullptr;
};

cpp文件

ModalDialog::ModalDialog(QWidget* parent)
    :QDialog(parent)
{
    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    m_pContentLabel = new QLabel();
    m_pContentLabel->setMinimumSize(200, 120);
    m_pContentLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    mainLayout->addWidget(m_pContentLabel);

    // 添加按钮
    QPushButton* okButton = new QPushButton("确定");
    QPushButton* cannelButton = new QPushButton("取消");
    QHBoxLayout* bottomLayout = new QHBoxLayout();
    bottomLayout->addStretch();
    bottomLayout->addWidget(okButton);
    bottomLayout->addWidget(cannelButton);
    mainLayout->addLayout(bottomLayout);

    // 连接信号
    QObject::connect(okButton, &QPushButton::clicked, this, &ModalDialog::clickedOKButton);
    QObject::connect(cannelButton, &QPushButton::clicked, this, &ModalDialog::clickedCannelButton);
}

ModalDialog::~ModalDialog()
{

}

void ModalDialog::setContentText(const QString& text)
{
    m_pContentLabel->setText(text);
}

整体对话框是继承自QDialog,界面实现内容比较简单。

接下来是调用部分:

void MainWindow::onClickedModalButton(void)
{
    ModalDialog dialog(this);
    dialog.setContentText("模态对话框");
    QObject::connect(&dialog, &ModalDialog::clickedOKButton, &dialog, &ModalDialog::accept);
    QObject::connect(&dialog, &ModalDialog::clickedCannelButton, &dialog, &ModalDialog::reject);

    if (dialog.exec() == ModalDialog::Accepted)
        m_pTextEdit->append("Modal: Clicked OK Button");
    else
        m_pTextEdit->append("Modal: Clicked Cannel Button");
    m_pTextEdit->append("Closed Modal Window");
}

点击 模态对话框 后,调用这部分代码

  • dialog.exec() , 函数 exec() 会调用显示一个模态对话框,并使代码不能向下运行,直到该函数返回。
  • accept() 这是一个槽函数,关联点击确定的信号。当点击按钮时,函数 exec() 返回 Accepted
  • reject() 这是一个槽函数,关联点击取消的信号。当点击按钮时,函数 exec() 返回 Rejected
  • 当点击关闭按钮是,函数 exec() 也返回 Rejected 。 因此当点击关闭对话框时,输出 Modal: Clicked Cannel Button

2. 非模态对话框(Modeless)

非模态对话框 是独立于同一应用程序中的其他窗口而运行的对话框。例如,文字处理程序中的查找和替换对话框通常是非模态的,以允许用户与应用程序的主窗口和对话框交互。

下面是非模态对话框的展示效果:

其中对话框的内容部分与上面的模态相同,调用 部分有所差异:

void MainWindow::onClickedModelessButton(void)
{
    ModalDialog *dialog = new ModalDialog(this);
    QObject::connect(dialog, &ModalDialog::clickedOKButton, \
                     [&]()->void{m_pTextEdit->append("Modeless: Clicked OK Button");});
    QObject::connect(dialog, &ModalDialog::clickedCannelButton, \
                     [&]()->void{m_pTextEdit->append("Modeless: Clicked Cannel Button");});

    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setContentText("非模态对话框");
    dialog->show();
    m_pTextEdit->append("Created Modeless Window");
}
  • 直接使用函数 show 即可实现非模态对话框,本例子中指定了 parent 否则会出现点击父窗口子窗口跑到父窗口下面的情况。
  • 这里使用了 setAttribute(Qt::WA_DeleteOnClose) 表示当关闭是自动释放内存,否则窗口关闭时不会被自动释放。
  • 与模态对话框不同,当调用函数 show() 后,代码不会被阻塞,可以继续被执行。如果想被阻塞可以使用 QEventLoop 实现。

3. 半模态对话框

我们所说的 半模态 通常是指模态对话框但是代码不会被阻塞。

下面时一个半模态的效果示例:

调用部分代码如下:

void MainWindow::onClickedHalfModalButton(void)
{
    ModalDialog *dialog = new ModalDialog(this);
    QObject::connect(dialog, &ModalDialog::clickedOKButton, \
                     [&]()->void{m_pTextEdit->append("Half Modal: Clicked OK Button");});
    QObject::connect(dialog, &ModalDialog::clickedCannelButton, \
                     [&]()->void{m_pTextEdit->append("Half Modal: Clicked Cannel Button");});
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setModal(true);
    dialog->setContentText("半模态对话框");
    dialog->show();

    m_pTextEdit->append("Created Half Modal Window");
}
  • 这里使用函数 setModal(true) 指定窗口为模态窗口。也可以使用函数 setWindowModality() 实现。
  • 调用函数 show() 后, 代码继续向下执行,而不是阻塞在此处。
不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:Qt绘制文字轮廓