QT自定义Widget实现鼠标拖动窗口移动位置及鼠标拖拽窗口边缘窗口大小改变

QT自定义Widget实现鼠标拖动窗口移动位置及鼠标拖拽窗口边缘窗口大小改变

通过setWindowFlags(Qt::FramelessWindowHint);可以隐藏掉Qt自带的窗口标题,这句话写的简单,可是窗口引起的改变可不少:

  • 最直观的,标题栏没了
  • 间接的,没了标题栏,也没有办法拖拽标题栏移动窗口位置了
  • 隐含的,鼠标移动到窗口边缘时,鼠标形态不再改变,无法实现鼠标拖拽窗口边缘改变窗口大小

So,想使用自定义的窗体也是需要付出代价的。如果我既想自定义窗体,也想要让自定义的窗体,兼具鼠标拖动窗口移动位置及鼠标拖拽窗口边缘窗口大小改变的特性呢,那就继续往下看吧。

最新get到一个比较有趣的实现方式,想借着实现以上两个功能点来秀一哈。
下面直接上代码:
实现鼠标拖拽移动窗体的代码:

/*MoveWgt.h*/
#ifndef MOVEWGT_H
#define MOVEWGT_H
#include <QObject>
#include <QWidget>
#include <QMouseEvent>
#define Move_Wgt                                                           \
private:                                                                   \
void mousePressEvent(QMouseEvent *event)                                   \
{                                                                          \
    m_isPressed = true;                                                    \
    m_startMovePos = event->globalPos()-this->frameGeometry().topLeft();   \
}                                                                          \
void mouseMoveEvent(QMouseEvent *event)                                    \
{                                                                          \
    if(m_isPressed)                                                        \
    {                                                                      \
        move(this->mapToGlobal(event->pos() - m_startMovePos));            \
    }                                                                      \
}                                                                          \
void mouseReleaseEvent(QMouseEvent *)                                      \
{                                                                          \
    m_isPressed = false;                                                   \
}                                                                          \
private:                                                                   \
    bool m_isPressed = false;                                              \
    QPoint m_startMovePos;

#endif // MOVEWGT_H

实现拖拽改变窗体大小的代码:

/*DragWgt.h*/
#ifndef DRAGWGT1_H
#define DRAGWGT1_H
#include <QObject>
#include <QWidget>
#include <QMouseEvent>
#include "Windows.h"
#define Drag_Wgt                                                                          \
bool nativeEvent(const QByteArray &eventType, void *message, long *result)                \
{                                                                                         \
    MSG* pMsg = (MSG*)message;                                                            \
    switch (pMsg->message)                                                                \
    {                                                                                     \
    case WM_NCHITTEST:                                                                    \
    {                                                                                     \
        QPoint pos = mapFromGlobal(QPoint(LOWORD(pMsg->lParam), HIWORD(pMsg->lParam)));   \
        bool bHorLeft = pos.x() < g_nBorder;                                              \
        bool bHorRight = pos.x() > width() - g_nBorder;                                   \
        bool bVertTop = pos.y() < g_nBorder;                                              \
        bool bVertBottom = pos.y() > height() - g_nBorder;                                \
        if (bHorLeft && bVertTop)                                                         \
        {                                                                                 \
            *result = HTTOPLEFT;                                                          \
        }                                                                                 \
        else if (bHorLeft && bVertBottom)                                                 \
        {                                                                                 \
            *result = HTBOTTOMLEFT;                                                       \
        }                                                                                 \
        else if (bHorRight && bVertTop)                                                   \
        {                                                                                 \
            *result = HTTOPRIGHT;                                                         \
        }                                                                                 \
        else if (bHorRight && bVertBottom)                                                \
        {                                                                                 \
            *result = HTBOTTOMRIGHT;                                                      \
        }                                                                                 \
        else if (bHorLeft)                                                                \
        {                                                                                 \
            *result = HTLEFT;                                                             \
        }                                                                                 \
        else if (bHorRight)                                                               \
        {                                                                                 \
            *result = HTRIGHT;                                                            \
        }                                                                                 \
        else if (bVertTop)                                                                \
        {                                                                                 \
            *result = HTTOP;                                                              \
        }                                                                                 \
        else if (bVertBottom)                                                             \
        {                                                                                 \
            *result = HTBOTTOM;                                                           \
        }                                                                                 \
        else                                                                              \
        {                                                                                 \
            return false;                                                                 \
        }                                                                                 \
        return true;                                                                      \
    }                                                                                     \
        break;                                                                            \
    default:                                                                              \
        break;                                                                            \
    }                                                                                     \
    return QWidget::nativeEvent(eventType, message, result);                              \
}                                                                                         \
private:                                                                                  \
    int g_nBorder = 4;

#endif // DRAGWGT_H

咋用到程序里面呢?直接上代码:

#ifndef TESTWGT_H
#define TESTWGT_H

#include <QWidget>
#include "movewgt.h"
#include "dragwgt.h"

namespace Ui {
class TestWgt;
}

class TestWgt : public QWidget
{
    Q_OBJECT
    
    //对的,就是这两行代码,其他的请略过
    Move_Wgt//-------------实现窗体鼠标按住拖拽可移动
    Drag_Wgt//-------------实现鼠标拖拽边缘窗体大小改变
    
public:
    explicit TestWgt(QWidget *parent = nullptr);
    ~TestWgt();

private:
    Ui::TestWgt *ui;
};

#endif // TESTWGT_H

注意奥,因为在MoveWgt.h中已经定义过 mousePressEvent、 mouseMoveEvent、 mouseReleaseEvent三个函数,所以在TestWgt中不能再重写该函数,否则编译会出现函数重定义的问题,DragWgt.h文件中相同。如果在自己的类中有需要重写以上函数的需要,可以不采用宏导入的这种方式,功能的实现方式不变,具体的就不在此赘述了。

  • 14
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值