前言
之前写过一篇博文《Qt鼠标拖动绘制基本几何图形》 ,这是介绍使用QGraphic中利用鼠标事件实现基本几何图形的绘制,支持直线、矩形、圆形、椭圆,本次是在此基础上进行扩展,实现背景图导入,并在图片上进行几何图形绘制,包括矩形、圆形等,支持画布整体移动、放大和缩小,画布恢复,图形item选中、移动、旋转、item移动,会实时显示全局坐标以及相对于背景画布的坐标。
本文提供基本功能实现,便于后期在此基础上进行扩展。
先看效果图:
本文Demo下载
正文
在《Qt鼠标拖动绘制基本几何图形》文中已经介绍了绘制几何图形的基本逻辑,这里就不再赘述。本文扩展的首要内容是导入一张图片后在被禁图上进行绘制,缩放和移动也是跟随整个背景来进行的,所以在导入图片后首先要根据图片的尺寸来创建一个父item
void GsMainScene::createRootItem(const QString &imgPath)
{
if(m_pRootItem){
SAFE_DELETE(m_pRootItem)
}
auto img = QImage(imgPath);
auto imgSize = img.size();
QSizeF newSize;
if((qreal)imgSize.width()/imgSize.height() > (qreal)sceneRect().width()/sceneRect().height()){
newSize.setWidth(sceneRect().width());
newSize.setHeight((qreal)imgSize.height()*sceneRect().width()/imgSize.width());
}
else{
newSize.setHeight(sceneRect().height());
newSize.setWidth((qreal)imgSize.width()*sceneRect().height()/imgSize.height());
}
m_pRootItem = new GsRootItem(newSize);
connect(m_pRootItem,&GsRootItem::sigPosInfoChanged,this,&GsMainScene::sigPosInfoChanged);
addItem(m_pRootItem);
m_pRootItem->moveBy(sceneRect().width()/2-newSize.width()/2.,sceneRect().height()/2.-newSize.height()/2.);
m_pRootItem->setBackgroudImage(img);
m_pRootItem->setImgScaleRatio((qreal)newSize.height()/imgSize.height());
emit sigPosInfoChanged(""); //清空
}
接下来再通过鼠标绘制的几何图形都是以这个rootItem为父类,这样就可以整体进行移动和缩放。
缩放代码:
void GsMainScene::scaleView(GsScaleType type)
{
auto view = views().first();
QTransform oldMatrix = view->transform();
view->resetTransform();
view->translate(oldMatrix.dx(), oldMatrix.dy());
if(type == Scale_Zoom_In){
m_nScaleValue += 5;
}
else if(type == Scale_Zoom_Out){
m_nScaleValue -= 5;
}
else if(type == Scale_Reset){
m_nScaleValue = 100;
}
view->scale(m_nScaleValue/100., m_nScaleValue/100.);
}
接下来图形的旋转,鼠标移动到图形的右下角按住鼠标左键旋转鼠标可以实现图形旋转,这个需要在对应的图元中处理鼠标移动事件来实现:
void GsShapeRectangeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
if(m_bRotate){
// 设置中心点为原点
QPointF originPos = this->boundingRect().center();
// 从原点延伸出去两条线,鼠标按下时的点和当前鼠标位置所在点的连线
QLineF p1 = QLineF(originPos, m_initPos);
QLineF p2 = QLineF(originPos, e->pos());
// 旋转角度
qreal dRotateAngle = p2.angleTo(p1);
// 旋转中心
this->setTransformOriginPoint(originPos);
// 计算当前旋转的角度
qreal dCurAngle = this->rotation() + dRotateAngle;
while (dCurAngle > 360.0) {
dCurAngle -= 360.0;
}
// 设置旋转角度
this->setRotation(dCurAngle);
this->update();
}
else{
QGraphicsObject::mouseMoveEvent(e);
}
}
以上是几个实现的关键代码,绘制图形部分在《Qt鼠标拖动绘制基本几何图形》中已经介绍过。
演示Demo中还包含了绘制直线、椭圆等,旋转图形只在四边形中实现了
其它图形要实现旋转也是同样的道理。
在之前的文章《Qt 鼠标/触屏绘制平滑曲线,支持矢量/非矢量方式》中还介绍了如何在QGraphic中通过鼠标绘制曲线,可以集成进来支持更多丰富的功能,达到自己想要的效果。
扩展
相关博文
Qt鼠标拖动绘制基本几何图形
Qt 鼠标/触屏绘制平滑曲线,支持矢量/非矢量方式
Qt 实现钢笔画线效果详细原理
本文Demo下载