鼠标拖动调整窗口大小——Qt

参考:Qt——鼠标拖动调整窗口大小 - 去冰三分糖 - 博客园 (cnblogs.com)

要求:鼠标移到界面边角时,鼠标样式相应地发生改变。

实现方法一:

重写mouseMoveEvent,如果鼠标没有按下,则根据鼠标在界面上的位置设置鼠标样式,如果鼠标按下,则根据位置判断该怎样调整界面大小,或者是拖动界面。思路如上,实现起来很简单。但是存在一个问题,如果界面中放了一些其它控件,比如listWidget,此时鼠标在界面边缘移动速度稍微快一些,mouseMoveEvent就会被子控件截获了,鼠标样式不会改变,对于该方法的这个问题,我还没想到好的解决办法。

ps:

类似参考:QT实现鼠标拖动调整窗口大小_Dawn丶的博客-CSDN博客

我这边就是遇到了这种鼠标样式不会变的情况,当时还很疑惑,明明逻辑对,但是就是不成功!所以,我这边因为系统只需要支持Windows,所以我就想找通过Windows方法实现此功能(也就是下面的方法二),然后就发现个这篇博客,美中不足的是:此博客的方法三的文件下载路径失效了,希望我有时间后,进行补充!

实现方法二:

此方法只适用于Windows系统,原作者的代码有些问题(信号槽无法响应),调试了半天才找到问题(应该是某个不是边缘的,返回的true,无法传给其他事件,比如信号槽);后续重新写的逻辑(也是参考网上已有的代码),这个应该没问题了 。

还有补充一下:Qt4用的是winEvent,Qt5用的是nativeEvent,因为我觉得我不会用到Qt4,所以以下代码也没有进行兼容操作。

#ifndef MBASEWIDGET_H

#define MBASEWIDGET_H



#include <QtWidgets/QWidget>

#include "windows.h"



class MBaseWidget : public QWidget

{

    Q_OBJECT



public:

    MBaseWidget(QWidget *parent);

    ~MBaseWidget();

    void setMarginWidth(const int &);           //设置鼠标可以在界面边缘多大范围内拖动改变界面大小

    void serResizable(bool);                    //设置是否可以拖动改变大小



protected:

    bool nativeEvent(const QByteArray & eventType, void * message, long * result);


private:

    int m_iMarginWidth;

    bool m_bCanResize;

};



#endif // MBASEWIDGET_H

#include "MBaseWidget.h"

#include "windowsx.h"



MBaseWidget::MBaseWidget(QWidget *parent)

    : QWidget(parent)

{

    m_iMarginWidth = 3;
    m_bCanResize = true;
    setWindowFlags(Qt::FramelessWindowHint);

}


MBaseWidget::~MBaseWidget()

{
}



void MBaseWidget::setMarginWidth(const int &iWidth)

{

    m_iMarginWidth = iWidth;

}

void MBaseWidget::serResizable(bool bCanResize)

{

    m_bCanResize = bCanResize;

}

bool MBaseWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    if (!m_bCanResize)
    {
        return QWidget::nativeEvent(eventType,message,result);
    }

    MSG* msg = (MSG*)message;
    switch(msg->message)
        {
        case WM_NCHITTEST:

            int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
            int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
            if(xPos < m_iMarginWidth && yPos<m_iMarginWidth)                    //左上角
                *result = HTTOPLEFT;
            else if(xPos>=width()-m_iMarginWidth&&yPos<m_iMarginWidth)          //右上角
                *result = HTTOPRIGHT;
            else if(xPos<m_iMarginWidth&&yPos>=height()-m_iMarginWidth)         //左下角
                *result = HTBOTTOMLEFT;
            else if(xPos>=width()-m_iMarginWidth&&yPos>=height()-m_iMarginWidth)//右下角
                *result = HTBOTTOMRIGHT;
            else if(xPos < m_iMarginWidth)                                     //左边
                *result =  HTLEFT;
            else if(xPos>=width()-m_iMarginWidth)                              //右边
                *result = HTRIGHT;
            else if(yPos<m_iMarginWidth)                                       //上边
                *result = HTTOP;
            else if(yPos>=height()-m_iMarginWidth)                             //下边
                *result = HTBOTTOM;
            else              //其他部分不做处理,返回false,留给其他事件处理器处理
               return false;
            return true;
        }
        return false;         //此处返回false,留给其他事件处理器处理

}

这种方法是借助windows来实现的,所以受系统的限制,比如,拖动放大到与屏幕一样大时,就不能继续放大了。

实现方法三:

既然通过mouseMoveEvent不能解决鼠标的样式问题,那么可以考虑通过其它事件来实现,下面是我实现的一个类,包括头文件、dll和lib文件。

在VS中项目属性-链接器中进行相关配置即可。(此文件下载路径失效了~,好可惜,但是也提供了一条思路!)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值