本文共 4680 字,大约阅读时间需要 15 分钟。
最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整。便在此重新书写了完整的代码,并开源出来。窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口。其效果图如下:
(1)slidingwindow.h
#ifndef SLIDINGWINDOW_H#define SLIDINGWINDOW_H#includeclass 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(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 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"#includeint 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:。 (3)若有问题或建议,请留言,在此感谢!