开发的时候经常要自定义widget窗体,UI都是自定义的布局,所以没有标题栏,想要进行拖拽需要自己处理,所以写成了一个类,方便使用。
FramelessHelper.h
#ifndef FRAMELESSHELPER
#define FRAMELESSHELPER
#include <QWidget>
#include <QObject>
class FramelessHelper : public QObject
{
Q_OBJECT
public:
GNFramelessHelper(QWidget *pParent);
protected:
bool eventFilter(QObject *obj, QEvent *ev);
private:
QWidget *widget;
QPoint pos;
bool isPressed;
};
#endif // FRAMELESSHELPER
FramelessHelper.cpp
#include "FramelessHelper.h"
#include <QMouseEvent>
#include <QEvent>
#include <QDebug>
#include <windows.h>
#include <windowsx.h>
#include <QApplication>
#include <QScreen>
FramelessHelper::FramelessHelper(QWidget *pParent):
widget(pParent),
isPressed(false)
{
widget->installEventFilter(this);
widget->setMouseTracking(true);
}
bool FramelessHelper::eventFilter(QObject *obj, QEvent *ev)
{
if(obj == widget)
{
QMouseEvent *event = dynamic_cast<QMouseEvent*>(ev);
if(event)
{
if(event->type() == QEvent::MouseButtonPress)
{
pos = event->globalPos();
isPressed = true;
}
else if(event->type() == QEvent::MouseButtonRelease)
{
isPressed = false;
}
else if(event->type() == QEvent::MouseMove)
{
if(isPressed && widget->cursor().shape() == Qt::ArrowCursor)
{
QPoint curPos = event->globalPos();
QPoint gap = curPos - pos;
QPoint newPos = widget->pos() + gap;
QSize screenSize = qApp->primaryScreen()->geometry().size();
newPos.setX(qMax(0, newPos.x()));
newPos.setX(qMin(screenSize.width() - widget->width(), newPos.x()));
newPos.setY(qMax(0, newPos.y()));
newPos.setY(qMin(screenSize.height() - widget->height(), newPos.y()));
widget->move(newPos);
pos = curPos;
}
}
}
}
return QObject::eventFilter(obj, ev);
}
使用起来就很简单了,对应窗体构造函数里new出来,把this指针传进去即可。
#include "FramelessHelper.h"
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
new FramelessHelper(this);
}
然后就可以实现窗体拖拽了,很方便。