Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口

来源:互联网 发布:个人展示网站源码 编辑:程序博客网 时间:2024/06/04 19:08

一、简介

        最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整。便在此重新书写了完整的代码,并开源出来。窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口。其效果图如下:

二、详解

1、代码

(1)slidingwindow.h
#ifndef SLIDINGWINDOW_H#define SLIDINGWINDOW_H#include <QtGui>class SlidingWindow : public QWidget{    Q_OBJECTpublic:    SlidingWindow(QWidget *parent = 0);    ~SlidingWindow();protected:    void mousePressEvent ( QMouseEvent * event);    void mouseMoveEvent(QMouseEvent *event);    void mouseReleaseEvent(QMouseEvent *event);    void resizeEvent(QResizeEvent *event);    bool eventFilter(QObject *obj, QEvent *event);private:    void setBtnPos();    void setBtnIcon();private slots:    void slotClickedBtn();    void slotSplitterMoved(int pos, int index);private:    QPoint dragPosition;    bool bPressFlag;    QSplitter *splitter;    QFrame *contentFrame;    QFrame *listFrame;    QPushButton *pushButton;    QIcon leftIcon;    QIcon rightIcon;};#endif // SLIDINGWINDOW_H
(2)slidingwindow.cpp
#include "slidingwindow.h"SlidingWindow::SlidingWindow(QWidget *parent)    : QWidget(parent, Qt::FramelessWindowHint)    , bPressFlag(false){    resize(660, 460);    splitter = new QSplitter(Qt::Horizontal, this);    splitter->setHandleWidth(1);    splitter->setStyleSheet("QSplitter::handle{background:#FFFFFF}");    contentFrame = new QFrame(splitter);    contentFrame->setStyleSheet("background:#000000");    contentFrame->resize(475, height());    contentFrame->setMinimumWidth(405);    listFrame = new QFrame(splitter);    listFrame->setStyleSheet("background:#323232");    listFrame->resize(660 - 475, height());    listFrame->setMaximumWidth(660 - 405);    connect(splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(slotSplitterMoved(int,int)));    leftIcon = QIcon(":/left.png");    rightIcon = QIcon(":/right.png");    pushButton = new QPushButton(this);    pushButton->setFocusPolicy(Qt::NoFocus);    pushButton->hide();    pushButton->setFixedSize(13, 42);    pushButton->setIconSize(pushButton->size());    pushButton->setStyleSheet("border:none;");    pushButton->setIcon(rightIcon);    pushButton->move(contentFrame->width() - pushButton->width()-2, (contentFrame->height() - pushButton->height())/2);    connect(pushButton,SIGNAL(clicked()),this,SLOT(slotClickedBtn()));    contentFrame->setMouseTracking(true);    listFrame->setMouseTracking(true);    contentFrame->installEventFilter(this);    listFrame->installEventFilter(this);}SlidingWindow::~SlidingWindow(){}void SlidingWindow::resizeEvent(QResizeEvent *event){    splitter->setGeometry(0, 0, width(), height());    move((QApplication::desktop()->width() - width())/2,  (QApplication::desktop()->height() - height())/2);    QWidget::resizeEvent(event);}bool SlidingWindow::eventFilter(QObject *obj, QEvent *event){    if (event->type() == QEvent::MouseMove) {        QMouseEvent *mouseMove = static_cast<QMouseEvent*>(event);        QRect rect = pushButton->frameGeometry();        if (rect.contains(mouseMove->pos())) {            pushButton->show();        }        else {            pushButton->hide();        }    }    return QWidget::eventFilter(obj, event);}void SlidingWindow::setBtnPos(){    pushButton->move(contentFrame->width() - pushButton->width(), (contentFrame->height() - pushButton->height())/2);}void SlidingWindow::setBtnIcon(){    if (listFrame->width() != 0) {        pushButton->setIcon(rightIcon);    }    else {        pushButton->setIcon(leftIcon);    }}void SlidingWindow::slotClickedBtn(){    QList <int> sizeList;    sizeList.clear();    if (listFrame->width() != 0) {        sizeList.append(660);        sizeList.append(0);    }    else {        sizeList.append(475);        sizeList.append(660 - 475);    }    splitter->setSizes(sizeList);    setBtnIcon();    setBtnPos();    pushButton->hide();}void SlidingWindow::slotSplitterMoved(int pos, int index){    Q_UNUSED(pos)    Q_UNUSED(index)    setBtnIcon();    setBtnPos();}void SlidingWindow::mousePressEvent ( QMouseEvent * event){    bPressFlag = true;    dragPosition = event->pos();    QWidget::mousePressEvent(event);}void SlidingWindow::mouseMoveEvent(QMouseEvent *event){    if (bPressFlag) {        QPoint relaPos(QCursor::pos() - dragPosition);        move(relaPos);    }    QWidget::mouseMoveEvent(event);}void SlidingWindow::mouseReleaseEvent(QMouseEvent *event){    bPressFlag = false;    QWidget::mouseReleaseEvent(event);}
(3)main.cpp
#include "slidingwindow.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    SlidingWindow w;    w.show();    return a.exec();}
(4)编译运行

三、总结

(1)获取位置坐标可以尝试QPoint realPos(QCursor::pos() - this->pos());,这样不用类型转换。主要设置setMouseTracking(true);才能当鼠标不点击时移动鼠标进入mouseMoveEvent事件函数。
(2)源码已上传到csdn:http://download.csdn.net/detail/taiyang1987912/9439233。
(3)若有问题或建议,请留言,在此感谢!

7 0