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开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

SQLite3命令行工具最佳实践指南

《SQLite3命令行工具最佳实践指南》SQLite3是轻量级嵌入式数据库,无需服务器支持,具备ACID事务与跨平台特性,适用于小型项目和学习,sqlite3.exe作为命令行工具,支持SQL执行、数... 目录1. SQLite3简介和特点2. sqlite3.exe使用概述2.1 sqlite3.exe

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

CnPlugin是PL/SQL Developer工具插件使用教程

《CnPlugin是PL/SQLDeveloper工具插件使用教程》:本文主要介绍CnPlugin是PL/SQLDeveloper工具插件使用教程,具有很好的参考价值,希望对大家有所帮助,如有错... 目录PL/SQL Developer工具插件使用安装拷贝文件配置总结PL/SQL Developer工具插

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

Python使用FFmpeg实现高效音频格式转换工具

《Python使用FFmpeg实现高效音频格式转换工具》在数字音频处理领域,音频格式转换是一项基础但至关重要的功能,本文主要为大家介绍了Python如何使用FFmpeg实现强大功能的图形化音频转换工具... 目录概述功能详解软件效果展示主界面布局转换过程截图完成提示开发步骤详解1. 环境准备2. 项目功能结

Linux系统之stress-ng测压工具的使用

《Linux系统之stress-ng测压工具的使用》:本文主要介绍Linux系统之stress-ng测压工具的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、理论1.stress工具简介与安装2.语法及参数3.具体安装二、实验1.运行8 cpu, 4 fo

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事