Qt加载消息应保持在父窗口小部件的顶部并居中

时间:2013-08-22 13:28:10

标签: c++ qt

如何创建一个QWidget(QDialog?),它保留在父Widgt之上,而不是其他应用程序,如Qt :: WindowsStaysOnTopHint?我想展示一点" loading"消息。

编辑:澄清

移动主窗口时,消息应保留在窗口小部件的居中位置。 我是否需要连接主窗口中的移动信号以手动将小部件保持在正确的位置?

我不想阻止整个应用程序本身(没有dialog.exec()),我只是想说用户应该等待并阻止用户输入(可能不是所有小部件,而是父小部件)< / p>

2 个答案:

答案 0 :(得分:2)

如果您仔细阅读QDialog::setModal()的文档,那么您应该找到合适的解决方案。 只需将带有paret的QDialog设置到您的窗口,并将其windowModality设置为Qt::WindowModal

文档说:

  

Qt :: WindowModal - 窗口是单个窗口层次结构的模态   阻止输入到其父窗口,所有祖父窗口以及所有窗口   其父母和祖父母窗户的兄弟姐妹。

答案 1 :(得分:0)

这是我的解决方案:

我没有使用setModal之类的东西。只需show()并隐藏()对话框,它应该保持在它的父对象之上。我添加了push和pop(就像一个堆栈),因为不同的线程可能对显示/隐藏对话框感兴趣...所以应该保证只有最后一次调用才会隐藏对话框。欢迎其他解决方案......这只是快速而肮脏。

class WaitDialog : public QDialog
{
    Q_OBJECT

    public:
        WaitDialog(const QString& message, QWidget *parent = 0);

public slots:
    void show();
    void hide();
    void push();
    void pop();

signals:
        void visibilityChanged(bool enable);

private:
    int stack;
        QLabel* msgLabel;
};

WaitDialog::WaitDialog(const QString &message, QWidget *parent)
: QDialog(parent, Qt::FramelessWindowHint),
      msgLabel(new QLabel(message, this)),
      stack(0)
{
    QVBoxLayout* mainLayout = new QVBoxLayout;
    mainLayout->setContentsMargins(30, 30, 30, 30);
    mainLayout->addWidget(msgLabel);
    setLayout(mainLayout);
}

void WaitDialog::show()
{
    QDialog::show();

        emit visibilityChanged(true);
}

void WaitDialog::hide()
{
    QDialog::hide();
    emit visibilityChanged(false);
}

void WaitDialog::push()
{
    stack++;
    show();

    emit visibilityChanged(true);
}

void WaitDialog::pop()
{
    if (stack > 0)
        --stack;
    if (stack == 0)
    {
        hide();
    }
}

所以我所做的只是

connect(someObject, SIGNAL(someProcessingFinished()), waitDialog, SLOT(pop()));

自动隐藏对话框并在开始处理时手动调用waitDialog-&gt; push()(或者将其连接到某些someProcessingStarted()方法)。

对话框本身以这种方式实例化:

WaitDialog * waitDialog = new WaitDialog(tr(“正在加载数据......请稍等。”),这个);

并将其父级放在第二个参数中(在本例中)。

让我可以让主窗口弹出一条消息,该消息只要停止ui交互所需的时间,但保持应用程序运行而不是等待对话框返回。未使用模态标志等。我只是将感兴趣的小部件连接到WaitDialog发出的visibilityChanged()信号。

connect(waitDialog, SIGNAL(visibilityChanged(bool)), someControl, SLOT(doSomething(bool)));

...例如,以下代码会在WaitDialog更改可见性时禁用/启用控件...

void SomeControl::doSomething(bool enabled)
{
    setEnabled(!enabled);
}

Look my question and answer here to get know how to keep it centered