Qt 鼠标拖动缩放
来源:互联网 发布:中兴通讯知乎 编辑:程序博客网 时间:2024/06/05 21:06
在Qt drag和drop基础上,实现QGraphicsItem的鼠标拖动缩放,效果如下:
如图所示,整个item由两个QGraphicsItem组成,item1用来显示主图片,item2用来显示移动光标。
先来看item2的实现,它实现的功能有显示和消失(鼠标移动到item周围显示,其他地方消失)、颜色改变(使用鼠标缩放时改变颜色)。
void CornerGrabber : : paint ( QPainter * painter ,
const QStyleOptionGraphicsItem* ,
QWidget * )
{
// fill the box with solid color, use sharp corners
_outterborderPen . setCapStyle ( Qt : : SquareCap );
_outterborderPen . setStyle ( Qt : : SolidLine );
painter - > setPen ( _outterborderPen );
QPointF topLeft ( 0 , 0 );
QPointF bottomRight ( _width , _height );
QRectF rect ( topLeft , bottomRight );
QBrush brush ( Qt : : SolidPattern );
brush . setColor ( _outterborderColor );
painter - > fillRect ( rect , brush );
}
const QStyleOptionGraphicsItem* ,
QWidget * )
{
// fill the box with solid color, use sharp corners
_outterborderPen . setCapStyle ( Qt : : SquareCap );
_outterborderPen . setStyle ( Qt : : SolidLine );
painter - > setPen ( _outterborderPen );
QPointF topLeft ( 0 , 0 );
QPointF bottomRight ( _width , _height );
QRectF rect ( topLeft , bottomRight );
QBrush brush ( Qt : : SolidPattern );
brush . setColor ( _outterborderColor );
painter - > fillRect ( rect , brush );
}
item2其实是一个巨型,宽和高由_width和_height确定,颜色由_outterborderColor确定,初始时黑色。
void CornerGrabber::hoverLeaveEvent( QGraphicsSceneHoverEvent* )
{
_outterborderColor = Qt::black;
this->update(0,0,_width,_height);
}
void CornerGrabber::hoverEnterEvent( QGraphicsSceneHoverEvent* )
{
_outterborderColor = Qt::red;
this->update(0,0,_width,_height);
}
{
_outterborderColor = Qt::black;
this->update(0,0,_width,_height);
}
void CornerGrabber::hoverEnterEvent( QGraphicsSceneHoverEvent* )
{
_outterborderColor = Qt::red;
this->update(0,0,_width,_height);
}
当进入item2的hover事件时,将_outterborderColor设置为红色,然后重新绘制,离开时再该回黑色。
void CornerGrabber::mouseMoveEvent(QGraphicsSceneDragDropEvent*event)
{
event->setAccepted(false);
}
void CornerGrabber::mousePressEvent(QGraphicsSceneDragDropEvent*event)
{
event->setAccepted(false);
}
void CornerGrabber::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
{
event->setAccepted(true);
}
void CornerGrabber::mousePressEvent( QGraphicsSceneMouseEvent* event )
{
event->setAccepted(false);
}
void CornerGrabber::mouseMoveEvent( QGraphicsSceneMouseEvent* event )
{
event->setAccepted(false);
}
{
event->setAccepted(false);
}
void CornerGrabber::mousePressEvent(QGraphicsSceneDragDropEvent*event)
{
event->setAccepted(false);
}
void CornerGrabber::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
{
event->setAccepted(true);
}
void CornerGrabber::mousePressEvent( QGraphicsSceneMouseEvent* event )
{
event->setAccepted(false);
}
void CornerGrabber::mouseMoveEvent( QGraphicsSceneMouseEvent* event )
{
event->setAccepted(false);
}
以上代码,表示item2自己处理mouseReleaseEvent事件(实际什么也不做),其他四种事件不处理。
下面看一下item1的实现。
void WorkspaceItem::paint(QPainter*painter,
const QStyleOptionGraphicsItem*option,
QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->drawPixmap(BoundDelta, BoundDelta, pixmap_);
if(isSelected())
{
painter->setPen(Qt::DashLine);
painter->drawRect(BoundDelta, BoundDelta, pixmap_width, pixmap_height);
}
}
const QStyleOptionGraphicsItem*option,
QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->drawPixmap(BoundDelta, BoundDelta, pixmap_);
if(isSelected())
{
painter->setPen(Qt::DashLine);
painter->drawRect(BoundDelta, BoundDelta, pixmap_width, pixmap_height);
}
}
先绘制中间显示的图片,如果被选中绘制虚线轮廓。
void WorkspaceItem::hoverEnterEvent(QGraphicsSceneHoverEvent*event)
{
Q_UNUSED(event)
corner = new CornerGrabber(this);
corner->installSceneEventFilter(this);
updateCornerPosition();
}
void WorkspaceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent*event)
{
Q_UNUSED(event)
delete corner;
}
{
Q_UNUSED(event)
corner = new CornerGrabber(this);
corner->installSceneEventFilter(this);
updateCornerPosition();
}
void WorkspaceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent*event)
{
Q_UNUSED(event)
delete corner;
}
这里跟item2类似,但又一点注册事件过滤器,用来处理item2不处理的四种事件(处理方法见下面函数)。
bool WorkspaceItem::sceneEventFilter(QGraphicsItem*watched, QEvent*event)
{
CornerGrabber* corner = dynamic_cast<CornerGrabber*>(watched);
if(corner == NULL)
return false;
QGraphicsSceneMouseEvent* mevent = dynamic_cast<QGraphicsSceneMouseEvent*>(event);
if(mevent == NULL)
return false;
switch(event->type())
{
case QEvent::GraphicsSceneMousePress:
corner->setMouseState(CornerGrabber::kMouseDown);
corner->mouseDownX= mevent->pos().x();
corner->mouseDownY= mevent->pos().y();
break;
case QEvent::GraphicsSceneMouseRelease:
corner->setMouseState(CornerGrabber::kMouseReleased);
break;
case QEvent::GraphicsSceneMouseMove:
corner->setMouseState(CornerGrabber::kMouseMoving );
break;
default:
return false;
}
if(corner->getMouseState()== CornerGrabber::kMouseMoving)
{
qreal x = mevent->pos().x(), y= mevent->pos().y();
qreal width = x - corner->mouseDownX+ pixmap_width;
qreal height = y - corner->mouseDownY+ pixmap_height;
QImage image;
if(text == "Mark")
image.load(":/images/banner_mark.png");
else
image.load(":/images/banner_text.png");
QSize size = image.size();
if(size.width() < pixmap_width || size.height() < pixmap_height)
{
width = size.width();
height = size.height();
}
qreal xscale = width / size.width();
qreal yscale = height / size.height();
qreal scale = qMax(xscale,yscale);
QMatrix matrix;
matrix.scale(scale, scale);
image = image.transformed(matrix);
pixmap_ = QPixmap::fromImage(image);
pixmap_width = pixmap_.width();
pixmap_height = pixmap_.height();
updateCornerPosition();
update();
scene()->update();
}
return true;
}
{
CornerGrabber* corner = dynamic_cast<CornerGrabber*>(watched);
if(corner == NULL)
return false;
QGraphicsSceneMouseEvent* mevent = dynamic_cast<QGraphicsSceneMouseEvent*>(event);
if(mevent == NULL)
return false;
switch(event->type())
{
case QEvent::GraphicsSceneMousePress:
corner->setMouseState(CornerGrabber::kMouseDown);
corner->mouseDownX= mevent->pos().x();
corner->mouseDownY= mevent->pos().y();
break;
case QEvent::GraphicsSceneMouseRelease:
corner->setMouseState(CornerGrabber::kMouseReleased);
break;
case QEvent::GraphicsSceneMouseMove:
corner->setMouseState(CornerGrabber::kMouseMoving );
break;
default:
return false;
}
if(corner->getMouseState()== CornerGrabber::kMouseMoving)
{
qreal x = mevent->pos().x(), y= mevent->pos().y();
qreal width = x - corner->mouseDownX+ pixmap_width;
qreal height = y - corner->mouseDownY+ pixmap_height;
QImage image;
if(text == "Mark")
image.load(":/images/banner_mark.png");
else
image.load(":/images/banner_text.png");
QSize size = image.size();
if(size.width() < pixmap_width || size.height() < pixmap_height)
{
width = size.width();
height = size.height();
}
qreal xscale = width / size.width();
qreal yscale = height / size.height();
qreal scale = qMax(xscale,yscale);
QMatrix matrix;
matrix.scale(scale, scale);
image = image.transformed(matrix);
pixmap_ = QPixmap::fromImage(image);
pixmap_width = pixmap_.width();
pixmap_height = pixmap_.height();
updateCornerPosition();
update();
scene()->update();
}
return true;
}
鼠标Press事件,记录鼠标位置
鼠标Move事件,如果数据左键是按下的,记录当前的位置,计算缩放后的大小和原先大小的比例,然后对图片按比例缩放
鼠标Release事件,什么多不做
以上是主要代码,完整源码:点击下载
- Qt 鼠标拖动缩放
- c# 鼠标拖动缩放图片
- QT --鼠标拖动界面
- QT 鼠标拖动无标题窗口
- [Unity3d]鼠标旋转缩放拖动模型
- [unity3d]鼠标拖动and旋转缩放
- Visio 用鼠标拖动和缩放画布
- Qt拖动鼠标移动窗体中的内容
- Qt里鼠标拖动窗口的实现
- QT界面,鼠标滚轮实现缩放问题
- QT界面,鼠标滚轮实现缩放问题
- C#图片处理总结——叠加、缩放、鼠标拖动
- C#实现图片鼠标拖动和滚动缩放
- c# WPF 中图片缩放功能,鼠标拖动位置
- touch.js 拖动、缩放、旋转 (鼠标手势)
- C# winfrom缩放图片并且可以鼠标拖动
- WPF无边框窗口鼠标拖动缩放大小
- Qt鼠标拖动ScrollArea代替鼠标滚轮操作
- C++ primer(九)--命名空间、定位new运算符
- CMFCMenuButton的基本用法
- google开源gumbo-parser系列
- HDU 3721 Building Roads
- C++ 虚函数表解析
- Qt 鼠标拖动缩放
- 啤酒与尿布:数据分析相关性分析案例一
- matlab产生莱斯分布随机数
- ios页面间传递参数四种方式
- 虚拟地址,逻辑地址,线性地址,物理地址有什么区别
- 快速排序——令程序陷入死循环的错误
- POJ 3254 状态压缩DP
- JavaIO(一)
- Java常用数据库连接字符串和驱动