之前做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)**也能达到同样的效果。
版权归原作者 花里云 所有, 如有侵权,请联系我们删除。