QT-可拖拉绘图工具

2023-12-19 12:44
文章标签 工具 qt 绘图 拖拉

本文主要是介绍QT-可拖拉绘图工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

QT-可拖拉绘图工具

  • 一、演示效果
  • 二、关键程序
  • 三、下载链接

一、演示效果

在这里插入图片描述

二、关键程序

#include "diagramscene.h"
#include "arrow.h"#include <QTextCursor>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>QPen const DiagramScene::penForLines = QPen(QBrush(QColor(Qt::black)), 2, Qt::PenStyle::DashLine);DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent): QGraphicsScene(parent)
{myItemMenu = itemMenu;myMode = MoveItem;myItemType = DiagramItem::Step;line = nullptr;textItem = nullptr;myItemColor = Qt::white;myTextColor = Qt::black;myLineColor = Qt::black;
}void DiagramScene::setLineColor(const QColor &color)
{myLineColor = color;foreach (QGraphicsItem* p, selectedItems()) {if (p->type() == Arrow::Type) {Arrow* item = qgraphicsitem_cast<Arrow*>(p);item->setColor(myLineColor);update();}}
}void DiagramScene::setTextColor(const QColor &color)
{myTextColor = color;foreach (QGraphicsItem* p, selectedItems()) {if (p->type() == DiagramTextItem::Type) {DiagramTextItem* item = qgraphicsitem_cast<DiagramTextItem*>(p);item->setDefaultTextColor(myTextColor);}}
}
//! [2]//! [3]
void DiagramScene::setItemColor(const QColor &color)
{myItemColor = color;foreach (QGraphicsItem* p, selectedItems()) {if (p->type() == DiagramItem::Type) {DiagramItem* item = qgraphicsitem_cast<DiagramItem*>(p);item->setBrush(myItemColor);}}
}void DiagramScene::setFont(const QFont &font)
{myFont = font;foreach (QGraphicsItem* p, selectedItems()) {if (p->type() == DiagramTextItem::Type) {DiagramTextItem* item = qgraphicsitem_cast<DiagramTextItem*>(p);item->setFont(myFont);}}
}void DiagramScene::deleteItems(QList<QGraphicsItem*> const& items) {qDebug() << "delete items" << items;QList<QGraphicsItem*> diagramItems;foreach (QGraphicsItem *item, items) {if (item->type() == Arrow::Type) {removeItem(item);Arrow *arrow = qgraphicsitem_cast<Arrow *>(item);arrow->startItem()->removeArrow(arrow);arrow->endItem()->removeArrow(arrow);delete item;} else diagramItems.append(item);}foreach (QGraphicsItem *item, diagramItems) {if (item->type() == DiagramItem::Type)qgraphicsitem_cast<DiagramItem *>(item)->removeArrows();removeItem(item);delete item;}
}
//! [4]void DiagramScene::setMode(Mode mode)
{myMode = mode;
}void DiagramScene::setItemType(DiagramItem::DiagramType type)
{myItemType = type;
}//! [5]
void DiagramScene::editorLostFocus(DiagramTextItem *item)
{QTextCursor cursor = item->textCursor();cursor.clearSelection();item->setTextCursor(cursor);if (item->toPlainText().isEmpty()) {removeItem(item);item->deleteLater();} else {if (item->contentIsUpdated()) {qDebug() << "content update ---";emit textChanged();}}}void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{if (mouseEvent->button() != Qt::LeftButton)return;DiagramItem *item;switch (myMode) {case InsertItem:item = new DiagramItem(myItemType, myItemMenu);item->setBrush(myItemColor);addItem(item);item->setPos(mouseEvent->scenePos());qDebug() << "insert item at: " << mouseEvent->scenePos();qDebug() << "\ttype: " << myItemType << " color: " << myItemColor;emit itemInserted(item);hasItemSelected = itemAt(mouseEvent->scenePos(), QTransform()) != nullptr;break;case InsertLine:if (itemAt(mouseEvent->scenePos(), QTransform()) == nullptr) break;line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(),mouseEvent->scenePos()));line->setPen(QPen(myLineColor, 2));addItem(line);break;case InsertText:textItem = new DiagramTextItem();textItem->setFont(myFont);textItem->setTextInteractionFlags(Qt::TextEditorInteraction);textItem->setZValue(1000.0);connect(textItem, SIGNAL(lostFocus(DiagramTextItem*)),this, SLOT(editorLostFocus(DiagramTextItem*)));connect(textItem, SIGNAL(selectedChange(QGraphicsItem*)),this, SIGNAL(itemSelected(QGraphicsItem*)));addItem(textItem);textItem->setDefaultTextColor(myTextColor);textItem->setPos(mouseEvent->scenePos());emit textInserted(textItem);qDebug() << "text inserted at" << textItem->scenePos();break;default:hasItemSelected = itemAt(mouseEvent->scenePos(), QTransform()) != nullptr;}QGraphicsScene::mousePressEvent(mouseEvent);
}void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) {if (myMode == InsertLine && line != nullptr) {QLineF newLine(line->line().p1(), mouseEvent->scenePos());line->setLine(newLine);} else if (myMode == MoveItem) {if (hasItemSelected)mouseDraggingMoveEvent(mouseEvent);QGraphicsScene::mouseMoveEvent(mouseEvent);}
}void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) {hasItemSelected = false;// leave sticky modehorizontalStickyMode = false;verticalStickyMode = false;foreach(QGraphicsItem* p, selectedItems())p->setFlag(QGraphicsItem::ItemIsMovable);clearOrthogonalLines();if (line != nullptr && myMode == InsertLine) {QList<QGraphicsItem *> startItems = items(line->line().p1());if (startItems.count() && startItems.first() == line)startItems.removeFirst();QList<QGraphicsItem *> endItems = items(line->line().p2());if (endItems.count() && endItems.first() == line)endItems.removeFirst();removeItem(line);delete line;if (startItems.count() > 0 && endItems.count() > 0 &&startItems.first()->type() == DiagramItem::Type &&endItems.first()->type() == DiagramItem::Type &&startItems.first() != endItems.first()) {DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(startItems.first());DiagramItem *endItem = qgraphicsitem_cast<DiagramItem *>(endItems.first());Arrow *arrow = new Arrow(startItem, endItem);arrow->setColor(myLineColor);startItem->addArrow(arrow);endItem->addArrow(arrow);arrow->setZValue(-1000.0);addItem(arrow);arrow->updatePosition();emit arrowInserted();}}line = nullptr;QGraphicsScene::mouseReleaseEvent(mouseEvent);
}void DiagramScene::wheelEvent(QGraphicsSceneWheelEvent* wheelEvent) {// ctrl key is being pressedif ((wheelEvent->modifiers() & Qt::KeyboardModifier::ControlModifier) != 0) {emit scaleChanging(wheelEvent->delta());wheelEvent->accept();} else {QGraphicsScene::wheelEvent(wheelEvent);}
}void DiagramScene::mouseDraggingMoveEvent(QGraphicsSceneMouseEvent* event) {clearOrthogonalLines();if ((event->buttons() & Qt::LeftButton) != 0 && selectedItems().size() == 1) {QGraphicsItem* itemUnderCursor = selectedItems().first();QPointF curCenter = itemUnderCursor->scenePos();QPointF const& mousePos = event->scenePos();foreach(QGraphicsItem* p, items()) {if (p->type() != DiagramItem::Type || p == itemUnderCursor) continue;DiagramItem* item = qgraphicsitem_cast<DiagramItem*>(p);QPointF const& objPoint = item->scenePos();LineAttr lineAttr;tryEnteringStickyMode(itemUnderCursor, objPoint, mousePos);if ((lineAttr = getPointsRelationship(objPoint, curCenter)) != Other) {if ((lineAttr & Horizontal) != 0) {QGraphicsLineItem* newHLine = new QGraphicsLineItem();newHLine->setLine(QLineF(QPointF(0, objPoint.y()),QPointF(sceneRect().width(), objPoint.y())));newHLine->setPen(penForLines);orthogonalLines.append(newHLine);}if ((lineAttr & Vertical) != 0) {QGraphicsLineItem* newVLine = new QGraphicsLineItem();newVLine->setLine(QLineF(QPointF(objPoint.x(), 0),QPointF(objPoint.x(), sceneRect().height())));newVLine->setPen(penForLines);orthogonalLines.append(newVLine);}}}tryLeavingStickyMode(itemUnderCursor, mousePos);}foreach(QGraphicsLineItem* p, orthogonalLines) {addItem(p);}
}void DiagramScene::clearOrthogonalLines() {foreach(QGraphicsLineItem* p, orthogonalLines) {removeItem(p);delete p;}orthogonalLines.clear();
}bool DiagramScene::closeEnough(qreal x, qreal y, qreal delta) {return std::abs(x - y) < delta;
}DiagramScene::LineAttr DiagramScene::getPointsRelationship(const QPointF& p1,const QPointF& p2) {int ret = Other;ret |= closeEnough(p1.x(), p2.x(), Delta) ? Vertical : Other;ret |= closeEnough(p1.y(), p2.y(), Delta) ? Horizontal : Other;return static_cast<DiagramScene::LineAttr>(ret);
}void DiagramScene::tryEnteringStickyMode(QGraphicsItem* item, const QPointF& target,const QPointF& mousePos) {QPointF const& itemPos = item->scenePos();if (!verticalStickyMode) {if (closeEnough(itemPos.x(), target.x(), stickyDistance)) {  // enter stickyModeverticalStickyMode = true;verticalStickPoint = mousePos;item->setFlag(QGraphicsItem::ItemIsMovable, false);item->setPos(QPointF(target.x(), itemPos.y()));}}if (!horizontalStickyMode) {if (closeEnough(itemPos.y(), target.y(), stickyDistance)) {horizontalStickyMode = true;horizontalStickPoint = mousePos;item->setFlag(QGraphicsItem::ItemIsMovable, false);item->setPos(QPointF(itemPos.x(), target.y()));}}
}void DiagramScene::tryLeavingStickyMode(QGraphicsItem* item, const QPointF& mousePos) {if (verticalStickyMode) { // already in stickyMode, item should be able to move verticallyitem->moveBy(0, mousePos.y() - verticalStickPoint.y());verticalStickPoint.setY(mousePos.y());// when to exit stickyMode?if (!closeEnough(mousePos.x(), verticalStickPoint.x(), stickyDistance)) {verticalStickyMode = false;item->setFlag(QGraphicsItem::ItemIsMovable, true);}}if (horizontalStickyMode) {item->moveBy(mousePos.x() - horizontalStickPoint.x(), 0);horizontalStickPoint.setX(mousePos.x());if (!closeEnough(mousePos.y(), horizontalStickPoint.y(), stickyDistance)) {horizontalStickyMode = false;item->setFlag(QGraphicsItem::ItemIsMovable, true);}}
}

三、下载链接

https://download.csdn.net/download/u013083044/88640602

这篇关于QT-可拖拉绘图工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/512202

相关文章

基于Python实现高效PPT转图片工具

《基于Python实现高效PPT转图片工具》在日常工作中,PPT是我们常用的演示工具,但有时候我们需要将PPT的内容提取为图片格式以便于展示或保存,所以本文将用Python实现PPT转PNG工具,希望... 目录1. 概述2. 功能使用2.1 安装依赖2.2 使用步骤2.3 代码实现2.4 GUI界面3.效

基于Python和MoviePy实现照片管理和视频合成工具

《基于Python和MoviePy实现照片管理和视频合成工具》在这篇博客中,我们将详细剖析一个基于Python的图形界面应用程序,该程序使用wxPython构建用户界面,并结合MoviePy、Pill... 目录引言项目概述代码结构分析1. 导入和依赖2. 主类:PhotoManager初始化方法:__in

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

jvm调优常用命令行工具详解

《jvm调优常用命令行工具详解》:本文主要介绍jvm调优常用命令行工具的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一 jinfo命令查看参数1.1 查看jvm参数二 jstack命令2.1 查看现场堆栈信息三 jstat 实时查看堆内存,gc情况3.1

MySQL使用binlog2sql工具实现在线恢复数据功能

《MySQL使用binlog2sql工具实现在线恢复数据功能》binlog2sql是大众点评开源的一款用于解析MySQLbinlog的工具,根据不同选项,可以得到原始SQL、回滚SQL等,下面我们就来... 目录背景目标步骤准备工作恢复数据结果验证结论背景生产数据库执行 SQL 脚本,一般会经过正规的审批

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并