QT布局之QSplitter

最近研究了QSplitier的类,发现它做布局的效果很好。不多说,先上图:QT布局之QSplitter

关于QSpliter,它可以通过insertWidget() 和addWidget()添加小部件到它的布局中去,并且可以通过拖动来改变这些小部件的大小。通过setSize可以设置所有小部件的大小。非常方便。下面就是源码, 有兴趣的同学可以研究下,如果有什么不对的地方请与我联系。

splitter.h

#ifndef SPLITTER_H
#define SPLITTER_H
#include <QIcon>
#include <QPoint>
#include <QWidget>


class QPushButton;
class QMouseEvent;
class QResizeEvent;
class QEvent;
class QObject;
class QSplitter;
class Splitter : public QWidget
{
    Q_OBJECT
public:
    explicit Splitter(QWidget *parent = 0);
    ~Splitter();

    void set_left_widget(QWidget *);
    QWidget *left_widget() const {return m_left_widget;}

    void set_right_widget(QWidget *);
    QWidget *right_widget() const {return m_right_widget;}


protected:
    void mousePressEvent(QMouseEvent *);

    void mouseMoveEvent(QMouseEvent *);

    void mouseReleaseEvent(QMouseEvent *event);

    void resizeEvent(QResizeEvent *event);

    bool eventFilter(QObject *obj, QEvent *event);

public slots:
    void slot_splitter_moved(int,int);

    void slot_button_click();

private:
    void updata_button_icon();
    void update_button_pos();


private:
    QPushButton *m_handle_button;
    QIcon m_left_icon;
    QIcon m_right_icon;
    QWidget *m_left_widget;
    QWidget *m_right_widget;
    QSplitter *m_splitter;

    bool m_press_flag;
    QPoint m_drag_postion;
};

#endif // SPLITTER_H

splitter.cc

#include "splitter.h"
#include <QPushButton>
#include <QWidget>
#include <QMouseEvent>
#include <QSplitter>
#include <QHBoxLayout>
Splitter::Splitter(QWidget *parent):
    QWidget(parent),
    m_left_icon(":/images/left.png"),
    m_right_icon(":/images/right.png"),
    m_press_flag(false),
    m_drag_postion()

{
    setWindowFlags(Qt::FramelessWindowHint);
    resize(800, 600);
    m_splitter = new QSplitter(this);
    QHBoxLayout *Hlayout = new QHBoxLayout;
    Hlayout->setMargin(0);
    Hlayout->setSpacing(0);
    Hlayout->addWidget(m_splitter);
    setLayout(Hlayout);
    m_splitter->setOrientation(Qt::Horizontal);
    m_splitter->setOpaqueResize(false);
    m_splitter->setHandleWidth(3);
    m_splitter->setStyleSheet("QSplitter::handle{background:rgb(200, 0, 0)}");

    m_left_widget = new QWidget(this);
    m_right_widget = new QWidget(this);
    m_left_widget->resize(200, height());
    m_right_widget->resize(width() - m_left_widget->width(), height());
    m_left_widget->setStyleSheet("background:rgb(10, 10, 10)");
    m_right_widget->setStyleSheet("background:rgb(100, 100, 100)");
    m_right_widget->setMouseTracking(true);
    m_left_widget->setMouseTracking(true);

    m_left_widget->installEventFilter(this);
    m_right_widget->installEventFilter(this);

    m_splitter->addWidget(m_left_widget);
    m_splitter->addWidget(m_right_widget);

    connect(m_splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(slot_splitter_moved(int,int)));

    m_handle_button = new QPushButton(this);
    m_handle_button->setFocusPolicy(Qt::NoFocus);
    m_handle_button->hide();
    m_handle_button->setFixedSize(23, 62);
    m_handle_button->setIconSize(m_handle_button->size());
    m_handle_button->setStyleSheet("background:rgb(230, 230, 230)");
    m_handle_button->setIcon(m_right_icon);
    connect(m_handle_button, SIGNAL(clicked()), this, SLOT(slot_button_click()));
}

Splitter::~Splitter()
{
}

void Splitter::set_left_widget(QWidget * widget)
{
    if (m_left_widget != NULL)
    {
        delete m_left_widget;
        m_left_widget = NULL;
    }
    m_left_widget = widget;
}

void Splitter::set_right_widget(QWidget *widget)
{
    if (m_right_widget != NULL)
    {
        delete m_right_widget;
        m_right_widget = NULL;
    }
    m_right_widget = widget;
}

void Splitter::mousePressEvent(QMouseEvent *event)
{
    m_press_flag = true;
    m_drag_postion = event->pos();
    QWidget::mousePressEvent(event);
}

void Splitter::mouseMoveEvent(QMouseEvent *)
{
    if (m_press_flag)
    {
        QPoint relaPos(QCursor::pos() - m_drag_postion);
        move(relaPos);
    }
}

void Splitter::mouseReleaseEvent(QMouseEvent *event)
{
    m_press_flag = false;
    QWidget::mouseReleaseEvent(event);
}

void Splitter::slot_splitter_moved(int, int)
{
    updata_button_icon();
    update_button_pos();
}

void Splitter::updata_button_icon()
{
    if (m_right_widget->width() != 0)
    {
        m_handle_button->setIcon(m_right_icon);
    }
    else
    {
        m_handle_button->setIcon(m_left_icon);
    }
}

void Splitter::update_button_pos()
{
    m_handle_button->move((left_widget()->width() -  m_handle_button->width()), (height() - m_handle_button->height())/2);
}

void Splitter::slot_button_click()
{
    QList <int> SizeList;
    SizeList.clear();
    if (m_right_widget->width() != 0) {
        SizeList.append(width() - m_left_widget->width());
        SizeList.append(0);
    }
    else
    {
        SizeList.append(width() - 200);
        SizeList.append(200);
    }

    m_splitter->setSizes(SizeList);
    updata_button_icon();
    update_button_pos();
    m_handle_button->hide();
}


void Splitter::resizeEvent(QResizeEvent *)
{
    update_button_pos();
}

bool Splitter::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::MouseMove && obj == m_left_widget)
    {
        QMouseEvent *mouseMove = static_cast<QMouseEvent*>(event);
        if (m_left_widget->width() - mouseMove->pos().x() < 20)
        {
            m_handle_button->show();
        }
        else
        {
            m_handle_button->hide();
        }
    }
    return QWidget::eventFilter(obj, event);
}

main.cc

#include <QWidget>
#include "mainwindow.h"
#include <QApplication>
#include "slidingwindow.h"
#include "splitter.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Splitter w;
    w.show();

    return a.exec();
}