QT 多层视图(视图叠加显示)

之前做Mac应用开发,视图层是可以上下叠加显示的,然后回到QT这边开发,发现QT的布局上不能叠加显示,于是写了个简单的可以叠加QWidget的小Demo

这是调用的代码:

#include "mainform.h"
#include "multilayoutwidget.h"

#include <QLabel>
#include <QVBoxLayout>
#include <QPushButton>

MainForm::MainForm(QWidget *parent)
    : QWidget(parent)
{
    MultiLayoutWidget *multiWidget = new MultiLayoutWidget(this);

    QVBoxLayout *vlayout1 = new QVBoxLayout;
    QLabel *label1 = new QLabel("AAAAAAAA");
    QLabel *label2 = new QLabel("BBBBBBBBBB");
    vlayout1->addWidget(label1);
    vlayout1->addWidget(label2);
    multiWidget->setLayout(vlayout1);

    QWidget *grayWidget = new QWidget;
    QVBoxLayout *vLayout2 = new QVBoxLayout;
    grayWidget->setLayout(vLayout2);
    multiWidget->addWidget(grayWidget);
    grayWidget->setStyleSheet("QWidget { background-color:rgba(150, 150, 150, 200); }");

    QLabel *label3 = new QLabel("CCCC");
    multiWidget->addWidget(label3);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(multiWidget);
    this->setLayout(mainLayout);
}


效果:

可以看出AAAAAA和BBBBB在最底层,中间层是一个半透明的灰色层,最上面层显示CCCCC。

AAAAAA和BBBBB被中间层遮盖,看起看没那清晰,最上面一层的CCCCC则非常清晰。

控件源码:

MultiLayoutWidget.h

#ifndef MULTILAYOUTWDGET_H
#define MULTILAYOUTWDGET_H

#include <QFrame>
#include <QEvent>

class MultiLayoutWidgetPrivate;
class MultiLayoutWidget : public QFrame
{
    Q_OBJECT
public:
    explicit MultiLayoutWidget(QWidget *parent = nullptr);

    /**
     * @brief 主层设置布局
     */
    void setLayout(QLayout*);

    /**
     * @brief 增加一层视图
     */
    void addWidget(QWidget*);

    /**
     * @brief 插入一层视图
     */
    void insertWidget(int index, QWidget*);

    /**
     * @brief 获取视图
     */
    QWidget *widget(int index);

    /**
     * @brief 删除视图层
     */
    void removeWidget(QWidget *);
    void removeWidget(int index);

    /**
     * @brief 该层是否获取鼠标事件,默认只有最顶层获取鼠标事件
     * @attention 该功能还没实现,后续有时间再更新
     */
    void widgetSetMouseEvent(QWidget*, bool state);
    void widgetSetMouseEvent(int index, bool state);

protected:
    bool event(QEvent*) override;

private:
    std::unique_ptr<MultiLayoutWidgetPrivate> d;
};

#endif // MULTILAYOUTWDGET_H

 MultiLayoutWidget.cpp

#include "multilayoutwidget.h"

#include <QList>

class MultiLayoutWidgetPrivate {
public:
    QWidget *mainWidget;
    QList<QWidget*> widgetList;
};

MultiLayoutWidget::MultiLayoutWidget(QWidget *parent)
    : QFrame{parent}
{
    d = std::make_unique<MultiLayoutWidgetPrivate>();
    d->mainWidget = new QWidget(this);
    d->mainWidget->raise();
}

void MultiLayoutWidget::setLayout(QLayout *layout)
{
    d->mainWidget->setLayout(layout);
}

void MultiLayoutWidget::addWidget(QWidget *widget)
{
    if(!widget) return;
    widget->setParent(this);
    d->widgetList.append(widget);
    widget->setGeometry(this->contentsRect());
    widget->raise();
}

void MultiLayoutWidget::insertWidget(int index, QWidget *widget)
{
    if(!widget) return;
    if(index > d->widgetList.size())
        index = d->widgetList.size();
    widget->setParent(this);
    d->widgetList.insert(index, widget);
    widget->setGeometry(this->contentsRect());
    widget->raise();

    for(int i = index + 1; i < d->widgetList.size(); ++i) {
        d->widgetList[i]->raise();
    }
}

QWidget *MultiLayoutWidget::widget(int index)
{
    if(index > d->widgetList.size())
        return nullptr;
    return d->widgetList[index];
}

void MultiLayoutWidget::removeWidget(QWidget *widget)
{
    if(d->widgetList.removeOne(widget)) {
        widget->deleteLater();
    }
}

void MultiLayoutWidget::removeWidget(int index)
{
    if(index < d->widgetList.size()) {
        QWidget *widget = d->widgetList[index];
        d->widgetList.removeAt(index);
        widget->deleteLater();
    }
}

void MultiLayoutWidget::widgetSetMouseEvent(QWidget *, bool state)
{

}

void MultiLayoutWidget::widgetSetMouseEvent(int index, bool state)
{

}

bool MultiLayoutWidget::event(QEvent *e)
{
    switch (e->type()) {
    case QEvent::Resize:
        d->mainWidget->setGeometry(this->contentsRect());
        foreach (QWidget *widget, d->widgetList) {
            widget->setGeometry((this->contentsRect()));
        }
        break;
    default:
        break;
    }

    return QWidget::event(e);
}

如果觉得对你有用,请点个赞。

补充

哈哈哈,后面发现使用QStackedLayout::setStackingMode(QStackedLayout::StackAll)也能达到同样的效果。

  • 12
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值