【问题标题】:Dialog with statusbar带有状态栏的对话框
【发布时间】:2014-09-18 06:31:34
【问题描述】:

我需要使用带有状态栏的对话框。我不知道如何在QDialog 中使用它,所以我使用QMainWindow。但是QMainWindow 没有exec() 函数,show() 函数异步工作。

我使用QtDesigner,但我不明白如何使用它添加状态栏。我也想在这个状态栏中看到widnow的小部件的状态提示。

【问题讨论】:

  • 为什么QDialog不能使用状态栏? QDialogQWidget。与QMainWindow 相同。您能描述一下您想要达到的最终结果吗?
  • 作为旁注/咆哮:阻止 GUI 的模式对话框通常是糟糕的 UI 设计。用户可能经常想在对话框打开时从主应用程序中检查一些东西,关闭对话框来检查它真的很烦人,也许复制粘贴到其他地方以便在对话框打开时可以查看它,然后重新打开对话框。尤其是对向导类型的多页对话框感到恼火,您可能已经填写了许多页面,然后需要重新执行所有操作。因此,如果有其他方法,请使用它,以获得更好的用户体验。有时只是使对话框非模态。

标签: c++ qt qmainwindow qdialog


【解决方案1】:

您可以使用QWidget::setWindowModality,可能是ApplicationModal or WindowModal,创建自己的对话框窗口模式,例如在其构造函数中。此外,您可能想要设置window flags for dialog,这样您就可以给对话框一个父级。因此,将这些添加到您的对话框主窗口构造函数中:

setWindowModality(Qt::ApplicationModal);
setWindowFlags(Qt::Dialog);

这样,即使有父窗口,它也会作为独立窗口打开,在关闭之前阻止 GUI 的其余部分,防止它获取用户输入事件。这应该与您使用 QDialog::open 时的行为相同。

要捕获用户关闭对话框,您可能应该向其中添加相同的signals as used by QDialog,并根据需要发出它们。这样您就可以将您的自定义对话框和QDialog 互换,而且您的代码也更容易理解(这称为静态多态性,赋予语义上不相关但功能相同的事物相同的名称)。


这是一些示例代码,DialogWindow自定义类的第一个构造函数:

DialogWindow ::DialogWindow (QWidget *parent) : QMainWindow(parent)
{
    setWindowFlags(Qt::Dialog);
    setWindowModality(Qt::ApplicationModal);
    setCentralWidget(new QLabel("Dialog")); // show some content
}

然后main函数使用它:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPushButton w("Open the Dialog"); // the "main window" of the whole application
    DialogWindow *dialog = new DialogWindow (&w);
    QObject::connect(&w, SIGNAL(clicked()), dialog, SLOT(show()));
    w.show();

    return a.exec();
}

【讨论】:

  • @Ufx 添加了对我有用的相关代码sn-ps
  • 我的 QMainWindow 派生类不是整个应用程序的“主窗口”。我不确定我是否正确,但它对我不起作用。窗口异步显示。
  • @Ufx 在我的示例中,QPushButton 是“主窗口”,我将对话窗口类重命名为“DialogWindow”以使其更清晰。但是,是的,它是异步的,就像您使用 QDialog::open 一样。因此,您需要在单独的插槽中处理对话的结果,答案中有一段关于此的内容。
  • 它有效。谢谢。但是为什么QMainWindow可以使用QtDesigner添加状态栏,而QDialog不能添加呢?
  • @Ufx QMainWindow的状态栏主要是它的特点,方便。您可以在任何 Qt 小部件中的任何位置添加QStatusBar,您只需自己完成,如其他答案所示。 QMainWindow 没有任何“魔法”,它只是内置了类似的代码。并且 Designer 为 QMainWindow 提供了一些硬编码功能,因此使用它创建普通桌面应用程序更加容易和快捷。
【解决方案2】:

QVBoxLayout 为例。

放置您需要的所有小部件并在底部添加QStatusBar

在 main.cpp 中:

QDialog dlg;
QLayout *l = new QVBoxLayout(&dlg);
QLabel *lbl = new QLabel("text");
QPushButton *bb = new QPushButton("text");
l->addWidget(bb);
l->addWidget(lbl);
QStatusBar *b = new QStatusBar;
l->addWidget(b);
b->showMessage("text");
l->setMargin(0);
l->setSpacing(0);
dlg.show();

更新:对于状态提示,您应该创建 QDialog 子类:

直径.h:

#ifndef DIA_H
#define DIA_H

#include <QDialog>
 #include <QStatusBar>
 #include <QLayout>
 #include <QApplication>
 #include <QTextEdit>
 #include <QStatusTipEvent>
 #include <QPushButton>

 class Dia : public QDialog {
 public:
    Dia() : QDialog()
    {
        QVBoxLayout *l = new QVBoxLayout(this);
        QTextEdit *te = new QTextEdit;
        te->setStatusTip("this is TextEdit");
        l->addWidget(te);
        QPushButton *bb = new QPushButton("tezt");
        bb->setStatusTip("this is button");
        l->addWidget(bb);
        bar = new QStatusBar;
        l->addWidget(bar);
        l->setMargin(0);
        l->setSpacing(0);
    }
 private:
    QStatusBar *bar;
 protected:
    bool event(QEvent *e)
    {
        if(e->type()==QEvent::StatusTip)
        {
            QStatusTipEvent *ev = (QStatusTipEvent*)e;
            bar->showMessage(ev->tip());
            return true;
        }
        return QDialog::event(e);
    }
 };
#endif // DIA_H

使用:

#include "dia.h"
//...    
Dia dlg;
dlg.show();

【讨论】:

  • 这可行,但是当光标位于小部件下方时,如何绘制状态提示?是否有可能使用 QtDesigner 做到这一点?
  • @Ufx,您没有在问题中提及状态文本。请扩展您的问题,以便每个人都知道您需要什么功能。
  • @Ufx 请查看我的更新,状态提示稍微复杂一些。我为每个小部件添加了一些小部件和 setStatusTip,并使代码更具可读性。
猜你喜欢
  • 1970-01-01
  • 2012-02-25
  • 2016-05-20
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多