gpt4 book ai didi

c++ - Qt 中 QMainWindow 上的深色透明层

转载 作者:IT老高 更新时间:2023-10-28 22:34:49 25 4
gpt4 key购买 nike

我需要在我的应用程序中实现一个“正在加载...”窗口,但我更喜欢用黑色透明层覆盖整个 QMainWindow,上面有一个文本。有人知道该怎么做吗?我不确定如何在 Qt 中重叠小部件/布局。任何帮助将不胜感激。

最佳答案

这个答案在我的一系列与叠加层相关的答案中:first , second , third .

最简单的解决方案是简单地将子透明小部件添加到QMainWindow。该小部件必须仅跟踪其父窗口的大小。正确处理小部件父级的更改以及与 sibling 的 z 顺序是很重要的。下面是一个正确的例子。

如果要堆叠叠加层,后续叠加层应该是 OverlayWidget 的子级,按 z 顺序排列。如果它们是 OverlayWidget 的 sibling ,它们的堆叠顺序是未定义的。

此解决方案的好处是与其他代码的耦合最小。它不需要您应用叠加层的小部件的任何知识。您可以将覆盖应用到 QMainWindow 或任何其他小部件,小部件也可以在布局中。

重新实现 QMainWindow 的绘制事件不会被认为是最好的设计。它使它与特定的类相关联。如果你真的认为 QWidget 实例的开销太大,你最好有测量来证明这种情况。

当然,也可以将覆盖层仅仅作为一个QObject 并将绘制代码放入一个事件过滤器中。那将是一个替代解决方案。这样做更难,因为您还必须正确处理父小部件的 Qt::WA_StaticContents 属性,并且小部件可能会调用其 scroll() 方法。处理单独的小部件是最简单的。

screenshot of the example

// https://github.com/KubaO/stackoverflown/tree/master/questions/overlay-widget-19362455
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif

class OverlayWidget : public QWidget
{
void newParent() {
if (!parent()) return;
parent()->installEventFilter(this);
raise();
}
public:
explicit OverlayWidget(QWidget * parent = {}) : QWidget{parent} {
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
newParent();
}
protected:
//! Catches resize and child events from the parent widget
bool eventFilter(QObject * obj, QEvent * ev) override {
if (obj == parent()) {
if (ev->type() == QEvent::Resize)
resize(static_cast<QResizeEvent*>(ev)->size());
else if (ev->type() == QEvent::ChildAdded)
raise();
}
return QWidget::eventFilter(obj, ev);
}
//! Tracks parent widget changes
bool event(QEvent* ev) override {
if (ev->type() == QEvent::ParentAboutToChange) {
if (parent()) parent()->removeEventFilter(this);
}
else if (ev->type() == QEvent::ParentChange)
newParent();
return QWidget::event(ev);
}
};

class LoadingOverlay : public OverlayWidget
{
public:
LoadingOverlay(QWidget * parent = {}) : OverlayWidget{parent} {
setAttribute(Qt::WA_TranslucentBackground);
}
protected:
void paintEvent(QPaintEvent *) override {
QPainter p{this};
p.fillRect(rect(), {100, 100, 100, 128});
p.setPen({200, 200, 255});
p.setFont({"arial,helvetica", 48});
p.drawText(rect(), "Loading...", Qt::AlignHCenter | Qt::AlignVCenter);
}
};

int main(int argc, char * argv[])
{
QApplication a{argc, argv};
QMainWindow window;
QLabel central{"Hello"};
central.setAlignment(Qt::AlignHCenter | Qt::AlignTop);
central.setMinimumSize(400, 300);
LoadingOverlay overlay{&central};
QTimer::singleShot(5000, &overlay, SLOT(hide()));
window.setCentralWidget(&central);
window.show();
return a.exec();
}

关于c++ - Qt 中 QMainWindow 上的深色透明层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19362455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com