#ifndef MOVEWIDGET_H
#define MOVEWIDGET_H #include <QWidget>
#include <QEvent> class MoveWidget : public QWidget
{
Q_OBJECT public:
MoveWidget(QWidget *parent);
~MoveWidget();
void setResizable(bool bResiable); //设置是否可以缩放
void setMargin(const int &); //设置鼠标距离界面边缘的范围 protected:
virtual bool eventFilter(QObject *, QEvent *); private:
void changeMouseStyle(const QPoint &);
private:
bool m_bResizable; //界面是否可以缩放
int m_iMarginWidth; //鼠标位置相对于界面边缘的距离
bool m_bPressed; //鼠标是否按下
QPoint m_ptPressPos;//鼠标按下时的位置
}; #endif // MOVEWIDGET_H

  

#include "MoveWidget.h"
#include <QHoverEvent> enum MouseStyle{ NORMAL, TOP, BOTTOM, LEFT, RIGHT, TOPLEFT, BOTTOMLEFT, BOTTOMRIGHT, TOPRIGHT } mouseStyle; MoveWidget::MoveWidget(QWidget *parent)
: QWidget(parent)
, m_bResizable(true)
, m_iMarginWidth(6)
, m_bPressed(false)
, m_ptPressPos(0, 0)
{
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
this->setAttribute(Qt::WA_Hover);
this->installEventFilter(this);
} MoveWidget::~MoveWidget()
{ } bool MoveWidget::eventFilter(QObject *, QEvent *event)
{
switch (event->type())
{
//[1]鼠标在界面上移动
case QEvent::HoverMove:
{
QHoverEvent *hoverEvent = dynamic_cast<QHoverEvent *>(event);
if (!m_bPressed)
{
changeMouseStyle(hoverEvent->pos());
}
else
{
if (mouseStyle == NORMAL)
{
this->move(this->mapToGlobal(hoverEvent->pos()) - m_ptPressPos);
return true;
}
QPoint ptGlobalPos = this->mapToGlobal(hoverEvent->pos());
QPoint ptTopLeft = this->frameGeometry().topLeft();
QPoint ptBottomRight = this->frameGeometry().bottomRight();
switch (mouseStyle)
{
case TOP:
if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
{
ptTopLeft.setY(ptGlobalPos.y());
}
else
{
ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
}
break;
case BOTTOM:
if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
{
ptBottomRight.setY(ptGlobalPos.y());
}
else
{
ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
}
break;
case LEFT:
if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
{
ptTopLeft.setX(ptGlobalPos.x());
}
else
{
ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
}
break;
case RIGHT:
if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
{
ptBottomRight.setX(ptGlobalPos.x());
}
else
{
ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
}
break;
case TOPLEFT:
if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
{
ptTopLeft.setX(ptGlobalPos.x());
}
else
{
ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
}
if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
{
ptTopLeft.setY(ptGlobalPos.y());
}
else
{
ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
}
break;
case BOTTOMLEFT:
if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
{
ptTopLeft.setX(ptGlobalPos.x());
}
else
{
ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
}
if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
{
ptBottomRight.setY(ptGlobalPos.y());
}
else
{
ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
}
break;
case BOTTOMRIGHT:
if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
{
ptBottomRight.setX(ptGlobalPos.x());
}
else
{
ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
}
if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
{
ptBottomRight.setY(ptGlobalPos.y());
}
else
{
ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
}
break;
case TOPRIGHT:
if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
{
ptTopLeft.setY(ptGlobalPos.y());
}
else
{
ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
}
if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
{
ptBottomRight.setX(ptGlobalPos.x());
}
else
{
ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
}
break;
default:
break;
}
this->setGeometry(QRect(ptTopLeft, ptBottomRight));
}
return true;
}
break;
//[1]end 鼠标在界面上移动 //[2]鼠标按下
case QEvent::MouseButtonPress:
{
m_bPressed = true;
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
m_ptPressPos = mouseEvent->globalPos() - this->frameGeometry().topLeft();
}
break;
//[2]end 鼠标按下 //[3]鼠标松开
case QEvent::MouseButtonRelease:
{
m_bPressed = false;
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
changeMouseStyle(mouseEvent->pos());
}
break;
//[3]end 鼠标松开 default:
break;
}
return false;
} void MoveWidget::changeMouseStyle(const QPoint &ptMousePos)
{
if (!m_bResizable)
{
setCursor(Qt::ArrowCursor);//正常样式
mouseStyle = NORMAL;
return;
}
int iPosX = ptMousePos.x();
int iPosY = ptMousePos.y(); int iWidth = this->width();
int iHeight = this->height();
if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth)
{
setCursor(Qt::SizeHorCursor);//右
if (iPosY >= 0 && iPosY <= m_iMarginWidth)
{
setCursor(Qt::SizeBDiagCursor);//右上
mouseStyle = TOPRIGHT;
return;
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
setCursor(Qt::SizeFDiagCursor);//右下
mouseStyle = BOTTOMRIGHT;
return;
}
mouseStyle = RIGHT;
return;
} if (iPosX >= 0 && iPosX <= m_iMarginWidth)
{
setCursor(Qt::SizeHorCursor);//左
if (iPosY >= 0 && iPosY <= m_iMarginWidth)
{
setCursor(Qt::SizeFDiagCursor);//左上
mouseStyle = TOPLEFT;
return;
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
setCursor(Qt::SizeBDiagCursor);//左下
mouseStyle = BOTTOMLEFT;
return;
}
mouseStyle = LEFT;
return;
} if (iPosY >= 0 && iPosY <= m_iMarginWidth)
{
setCursor(Qt::SizeVerCursor);//上
mouseStyle = TOP;
return;
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
setCursor(Qt::SizeVerCursor);//下
mouseStyle = BOTTOM;
return;
}
setCursor(Qt::ArrowCursor);//正常样式
mouseStyle = NORMAL;
return;
} void MoveWidget::setResizable(bool bResiable)
{
m_bResizable = bResiable;
} void MoveWidget::setMargin(const int &iWidth)
{
m_iMarginWidth = iWidth;
}

  

Qt——鼠标拖动缩放窗口源码的更多相关文章

  1. qt 鼠标拖动窗口放大缩小

    // 鼠标拖动 具体实现void mouseMoveEvent(QMouseEvent * pEvent) { if (pEvent->buttons() & Qt::LeftButto ...

  2. Bootstrap 模态窗口源码分析

    前言: bootstrap的 js插件的源码写的非常好,也算是编写jquery插件的模范写法,本来还想大篇详细的分析一下呢,唉,没时间啊,很早之前看过的源码了,现在贴在了博客上, 300来行的代码,其 ...

  3. AndroidTv Home界面实现原理(二)——Leanback 库的主页卡位缩放动画源码解析

    先看个效果图: 上一篇中,我们留了问题,在 Tv Home 界面这种很常见聚焦卡位放大动画效果,我们这一篇就来看看 Leanback 库是怎么实现的. 如果要我们自己实现的话,思路应该不难,就是写个放 ...

  4. Qt creator中文输入—fctix-qt5 源码编译 libfcitxplatforminputcontextplugin.so

    fctix-qt5 的源码有两个地方可以下载: wget https://download.fcitx-im.org/fcitx-qt5/fcitx-qt5-1.0.5.tar.xztar -xJf ...

  5. iOS电商常见动画与布局、微信悬浮窗、音乐播放器、歌词解析、拖动视图等源码

    iOS精选源码 MXScroll 介绍 混合使用UIScrollView ios 电商demo(实现各种常见动画效果和页面布局) 一行代码集成微信悬浮窗 可拖动,大小的视图,可放置在屏幕边缘. 在使用 ...

  6. QT:轻松获取网页源码

    获取网页源码的小例子,代码很简单,就不多作解释了. 不过一定要注意网页的编码问题,否则会出现乱码的!!! #include <QtCore> #include <QtNetwork& ...

  7. 40.qt quick- 高仿微信实现局域网聊天V4版本(支持gif动图表情包、消息聊天、拖动缩放窗口)

    在上章37.qt quick- 高仿微信实现局域网聊天V3版本(添加登录界面.UDP校验登录.皮肤更换.3D旋转),我们已经实现了: 添加登录界面. UDP校验登录. 皮肤更换. 3D旋转(主界面和登 ...

  8. qt 鼠标拖动窗口 跳动 解决

    因为获取当前的位置,似乎没有把标题栏的高度记进去. 所以移动前,得考虑到标题栏的高度. 用以下方式获取标题栏高度: QApplication::style()->pixelMetric(QSty ...

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

    要求:鼠标移到界面边角时,鼠标样式相应地发生改变. 实现方法一: 重写mouseMoveEvent,如果鼠标没有按下,则根据鼠标在界面上的位置设置鼠标样式,如果鼠标按下,则根据位置判断该怎样调整界面大 ...

随机推荐

  1. 成熟度等级CMM

    软件能力成熟度模型 (Capability maturity model,CMM) CMM是目前国际上使用流行的一种软件生产过程行业标准模型,可定义.评价软件开发过程的成熟度,并提供提高软件质量的指导 ...

  2. 菜鸟 Python 100例

    以下参考:菜鸟教程 python100例 == 推荐博客 有四个数字: 1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? import itertools a = ('1','2' ...

  3. 评估类模型之优劣解距离法Topsis模型

    定义: TOPSIS法是一种常用的综合评价方法,其能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距. 层次分析法的局限性: 问题和解决方案: 所以最终评分公式为: 指标正向化,得到正向 ...

  4. 005_FreeRTOS任务挂起和恢复

    (一) (二)使用,参数是任务句柄 //key任务函数 void key_task(void *pvParameters) { u8 key; ) { key=KEY_Scan(); switch(k ...

  5. 007_linuxC++之_构造函数的初级应用

    (一)构造函数:用来在创建对象时初始化对象, 即为对象成员变量赋初始值 (二)构造函数的命名必须和类名完全相同 (三)更对具体的查看:构造函数 (四)直接分析程序 运行结果 解析上面程序: 1. 当程 ...

  6. @Component,@Service,@Controller,@Repository

    1.@controller 控制器(注入服务) 2.@service 服务(注入dao) 3.@repository dao(实现dao访问) 4.@component (把普通pojo实例化到spr ...

  7. 带发送FIFO缓冲的RX232串口发送以及把众多文件变成“黑匣子”用于其它工程的调用

    如果需要发送端不断地接收新的数据,而发送端的数据传输率低就需要一个缓冲器FIFO来缓冲数据.当你为别人做项目只是想实现功能而不想让自己的代码让别人看到,想保护自己的算法时,你可以用以下的方法.我使用的 ...

  8. 以字符串为例,谈谈Python到底要学到什么程度

    古语云:慈不掌兵,义不为商:离商业越近,离人性越远:我们在自学数据科学时,一定会辅助一些书籍或者视频来学习,怎么学习,选择哪些资料来学习?这时,我们都要理解好第一句话,理解不好,浪费钱是次要,重要的是 ...

  9. combobox的js添加数据

    $("#int_cls").combobox({ valueField:'code', textField:'name', disabled:false }); var data, ...

  10. Leetcode题目337:打家劫舍 III(树形DP-中等)

    题目描述: 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为“根”. 除了“根”之外,每栋房子有且只有一个“父“房子与之相连.一番侦察之后,聪明 ...