要求:当鼠标移到界面的一角时,鼠标样式会相应更改。
方法一:
重写mouseMoveEvent。如果未按下鼠标,则根据界面上鼠标的位置来设置鼠标样式。如果按下鼠标,则根据位置判断如何调整界面大小或拖动界面。想法如上,很容易实现。但有一个问题。如果在界面中放置其他控件(例如listWidget),则鼠标在界面边缘的移动会稍快一些,子控件会拦截mouseMoveEvent,并且鼠标样式不会改变。对于这种方法的问题,我还没有想到一个好的解决方案。

方法二:
在Qt中处理Windows事件,具体实现如下,参考Internet上的一些内容,我通过方式进行了修改和优化,源代码如下:
#ifndef MBASEWIDGET_H #define MBASEWIDGET_H #include#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); bool winEvent(MSG *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;
}
//处理windows事件,在QT5中,被函数nativeEvent取代
bool MBaseWidget::winEvent(MSG *message, long *result)
{
switch (message->message)
{
case WM_NCHITTEST:
int iPosX = GET_X_LPARAM(message->lParam) - this->frameGeometry().x();//鼠标位置x
int iPosY = GET_Y_LPARAM(message->lParam) - this->frameGeometry().y();//鼠标位置y
*result = HTCAPTION;
if (!m_bCanResize)
{
return true;//返回为真,此时仍可拖动,但无法改变大小
}
if (iPosX >= 0 && iPosX <= m_iMarginWidth)
{
*result = HTLEFT;//左
int iHeight = this->height();
if (iPosY >= 0 && iPosY <= m_iMarginWidth)
{
*result = HTTOPLEFT;//左上
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
*result = HTBOTTOMLEFT;//左下
}
return true;
}
int iWidth = this->width();
int iHeight = this->height();
if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth)
{
*result = HTRIGHT;//右
if (iPosY >= 0 && iPosY <= m_iMarginWidth)
{
*result = HTTOPRIGHT;//右上
return true;
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
*result = HTBOTTOMRIGHT;//右下
return true;
}
return true;
}
if (iPosY >= 0 && iPosY <= m_iMarginWidth)
{
*result = HTTOP;//上
return true;
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
*result = HTBOTTOM;//下
return true;
}
return true;
}
return false;
}
bool MBaseWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
return winEvent((MSG*)message, result);
}
此方法是在Windows的帮助下实现的,因此受到系统的限制。例如,当拖动和缩放到与屏幕相同的大小时,缩放无法继续,其他类直接继承该类可能会导致问题。
方法三:

由于mouseMoveEvent无法解决鼠标样式问题,因此可以考虑其他事件来实现。下面是我实现的类,包括头文件,dll和lib文件。
在VS中的项目属性链接器中执行相关配置。
点击下载
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-352011-1.html
只求真相
我们的东风21