如何创建一个 QWidget(QDialog?),它保持在父 Widgt 之上,而不是像 Qt::WindowsStaysOnTopHint 这样的其他应用程序?我想显示一点“加载”消息。
编辑:澄清
移动主窗口时,消息应保持在小部件的中心位置。我是否需要连接主窗口中的移动信号以手动将小部件保持在正确的位置?
我不想阻止整个应用程序本身(没有 dialog.exec()),我只想说用户应该等待并阻止用户输入(可能不是所有小部件,而是父小部件)
如果您QDialog::setModal()
仔细阅读文档,那么您应该找到正确的解决方案。只需使用 QDialog 并将 paret 设置为您的窗口并将其windowModality设置为Qt::WindowModal。
文档说:
Qt::WindowModal - 窗口对单个窗口层次结构是模态的,并阻止对其父窗口、所有祖父窗口以及其父窗口和祖父窗口的所有兄弟窗口的输入。
这是我的解决方案:
我不使用 setModal 之类的东西。只需显示()和隐藏()对话框,它应该保持在它的父级之上。我添加了推送和弹出(如堆栈),因为不同的线程可能对显示/隐藏对话框感兴趣......所以应该保证只有最后一次调用隐藏对话框。欢迎其他解决方案......这只是快速而肮脏的。
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->push() (或将其连接到一些 someProcessingStarted() 方法)。
对话框本身就是这样实例化的:
WaitDialog* waitDialog = new WaitDialog(tr("正在加载数据...请稍候。"), this);
并在第二个参数中获得其父级(在示例中为 this)。
对我来说,让主窗口弹出一条消息,只要停止 ui 交互,但保持应用程序运行而不是等待对话框返回。未使用模态标志等。我只是将感兴趣的小部件连接到 WaitDialog 发出的 visibilityChanged() 信号。
connect(waitDialog, SIGNAL(visibilityChanged(bool)), someControl, SLOT(doSomething(bool)));
...例如,只要 WaitDialog 更改可见性,以下代码就会禁用/启用控件...
void SomeControl::doSomething(bool enabled)
{
setEnabled(!enabled);
}