Qt编写自定义控件:带按钮的分隔器

代码:

#include <QWidget>

class SplitterWithButton : public QWidget
{
    Q_OBJECT

public:
    SplitterWithButton(Qt::Orientation orientation,QWidget *parent = nullptr);
    void addWidget(QWidget *widget);

protected:
    void mouseMoveEvent(QMouseEvent *event)override;

private:
    enum class buttonPos
    {
        left,
        right,
        top,
        bottom
    };
    QList<QWidget *> widgetList;
    class QToolButton * btn;
    class QSplitter * splitter;
    void setButtonStyle(buttonPos pos);
    void onBtnClicked();
    buttonPos btnPos;
    int processWidgetIndex{-1};
};
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QSplitter>
#include <QToolButton>

SplitterWithButton::SplitterWithButton(Qt::Orientation orientation, QWidget *parent)
    : QWidget(parent)
{
    splitter = new QSplitter(orientation,this);
    splitter->setHandleWidth(5);
    splitter->setStyleSheet("QSplitter::handle{background-color:#00beac;}");

    splitter->setMouseTracking(true);
    setMouseTracking(true);

    btn = new QToolButton(this);
    btn->setCursor(Qt::PointingHandCursor);
    btn->setFocusPolicy(Qt::NoFocus);
    btn->hide();
    btn->setStyleSheet("border:none;");
    connect(btn,&QToolButton::clicked,this,&SplitterWithButton::onBtnClicked);

    auto hb = new QHBoxLayout;
    hb->setMargin(0);
    hb->addWidget(splitter);
    setLayout(hb);
}

void SplitterWithButton::onBtnClicked()
{
    if(processWidgetIndex != -1)
    {
        auto list = splitter->sizes();
        btn->hide();
        switch (btnPos)
        {
            case buttonPos::left:
            {
                auto sum = list[processWidgetIndex] + list[processWidgetIndex - 1];
                auto size = widgetList[processWidgetIndex - 1]->minimumSizeHint();
                list[processWidgetIndex] = sum - size.width();
                list[processWidgetIndex - 1] = size.width();
            }break;
            case buttonPos::right:
            {
                auto sum = list[processWidgetIndex] + list[processWidgetIndex + 1];
                auto size = widgetList[processWidgetIndex + 1]->minimumSizeHint();
                list[processWidgetIndex] = sum - size.width();
                list[processWidgetIndex + 1] = size.width();
            }break;
            case buttonPos::top:
            {
                auto sum = list[processWidgetIndex] + list[processWidgetIndex - 1];
                auto size = widgetList[processWidgetIndex - 1]->minimumSizeHint();
                list[processWidgetIndex] = sum - size.height();
                list[processWidgetIndex - 1] = size.height();
            }break;
            case buttonPos::bottom:
            {
                auto sum = list[processWidgetIndex] + list[processWidgetIndex + 1];
                auto size = widgetList[processWidgetIndex + 1]->minimumSizeHint();
                list[processWidgetIndex] = sum - size.height();
                list[processWidgetIndex + 1] = size.height();
            }break;
        }
        splitter->setSizes(list);
    }
}

void SplitterWithButton::setButtonStyle(buttonPos pos)
{
    switch (pos)
    {
        case buttonPos::left:
        {
            btn->setFixedSize(13,42);
            btn->setIcon(QIcon(":/img/right.png"));

        }break;
        case buttonPos::right:
        {
            btn->setFixedSize(13,42);
            btn->setIcon(QIcon(":/img/left.png"));

        }break;
        case buttonPos::top:
        {
            btn->setFixedSize(42,13);
            btn->setIcon(QIcon(":/img/bottom.png"));

        }break;
        case buttonPos::bottom:
        {
            btn->setFixedSize(42,13);
            btn->setIcon(QIcon(":/img/top.png"));
        }break;
    }
    btn->setIconSize(btn->size());
    btnPos = pos;
}

void SplitterWithButton::addWidget(QWidget *widget)
{
    widgetList << widget;
    widget->setMouseTracking(true);
    splitter->addWidget(widget);
}

void SplitterWithButton::mouseMoveEvent(QMouseEvent *event)
{
    auto p = event->pos();

    auto size = widgetList.size();
    for(int i = 0;i < size;++i)
    {
        auto & w = widgetList[i];
        QRect rect = w->frameGeometry();
        if (rect.contains(p))
        {
            if(splitter->orientation() == Qt::Horizontal)
            {
                QRect leftCenterRect = QRect(rect.x(),(rect.height() - 42)/2,13,42);
                QRect rightCenterRect = QRect(rect.x() + rect.width() - 13,(rect.height() - 42)/2,13,42);

                if(leftCenterRect.contains(p))//上一个是否符合条件,若不符合则不显示按钮
                {
                    if(i > 0)
                    {
                        if(widgetList[i - 1]->width() < 5)
                        {
                            setButtonStyle(buttonPos::left);
                            btn->move(leftCenterRect.topLeft());
                            btn->show();
                            processWidgetIndex = i;
                        }
                        else
                        {
                            btn->hide();
                            processWidgetIndex = -1;
                        }
                    }
                    else
                    {
                        processWidgetIndex = -1;
                    }
                }
                else if(rightCenterRect.contains(p))//下一个是否符合条件,若不符合则不显示按钮
                {
                    if(i != (size - 1))
                    {
                        if(widgetList[i + 1]->width() < 5)
                        {
                            setButtonStyle(buttonPos::right);
                            btn->move(rightCenterRect.topLeft());
                            btn->show();
                            processWidgetIndex = i;
                        }
                        else
                        {
                            btn->hide();
                            processWidgetIndex = -1;
                        }
                    }
                    else
                    {
                        processWidgetIndex = -1;
                    }
                }
                else
                {
                    btn->hide();
                }
            }
            else
            {
                QRect topCenterRect = QRect((rect.width() - 42)/2,rect.y(),42,13);
                QRect bottomCenterRect = QRect((rect.width() - 42)/2,rect.y() + rect.height() - 13,42,13);
                if(topCenterRect.contains(p))//上一个是否符合条件,若不符合则不显示按钮
                {
                    if(i > 0)
                    {
                        if(widgetList[i - 1]->height() < 5)
                        {
                            setButtonStyle(buttonPos::top);
                            btn->move(topCenterRect.topLeft());
                            btn->show();
                            processWidgetIndex = i;
                        }
                        else
                        {
                            btn->hide();
                            processWidgetIndex = -1;
                        }
                    }
                    else
                    {
                        processWidgetIndex = -1;
                    }
                }
                else if(bottomCenterRect.contains(p))//下一个是否符合条件,若不符合则不显示按钮
                {
                    if(i != (size - 1))
                    {
                        if(widgetList[i + 1]->height() < 5)
                        {
                            setButtonStyle(buttonPos::bottom);
                            btn->move(bottomCenterRect.topLeft());
                            btn->show();
                            processWidgetIndex = i;
                        }
                        else
                        {
                            btn->hide();
                            processWidgetIndex = -1;
                        }
                    }
                    else
                    {
                        processWidgetIndex = -1;
                    }
                }
                else
                {
                    btn->hide();
                }
            }

            break;
        }
    }

    QWidget::mouseMoveEvent(event);
}

使用:

    SplitterWithButton w(Qt::Horizontal);
    w.addWidget(new QLabel("哈哈哈"));
    w.addWidget(new QLabel("呵呵呵"));
    w.addWidget(new QLabel("啦啦啦"));

    w.resize(800,600);
    w.show();

可设置水平/垂直方向。

当分割的一部分隐藏时会在边缘显示按钮,点击按钮则显示:

垂直方向:

 

用到的图片:

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值