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

相关文章

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼?市面上那么多工具,常常让人无从选择。今天,想给大家安利一款神器——PixPin,一款真正解放双手的截图工具。 想象一下,你只需要按下快捷键就能轻松完成多种截图任务,还能快速编辑、标注甚至保存多种格式的图片。这款工具能满足这些需求吗? PixPin不仅支持全屏、窗口、区域截图等基础功能,它还可以进行延时截图,让你捕捉到每个关键画面。不仅如此

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

PR曲线——一个更敏感的性能评估工具

在不均衡数据集的情况下,精确率-召回率(Precision-Recall, PR)曲线是一种非常有用的工具,因为它提供了比传统的ROC曲线更准确的性能评估。以下是PR曲线在不均衡数据情况下的一些作用: 关注少数类:在不均衡数据集中,少数类的样本数量远少于多数类。PR曲线通过关注少数类(通常是正类)的性能来弥补这一点,因为它直接评估模型在识别正类方面的能力。 精确率与召回率的平衡:精确率(Pr

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所