qt绘制网络拓补图(连接数据库,递归函数,无限绘制,可拖动节点)
硬件:ThinkPadT590
系统:Win10
数据库:sqlserver2014
Qt:5.14.1
QtCreator:4.11.1
源码连接:
qt绘制网络拓补图(连接数据库,递归函数,无限绘制,可拖动节点)-QT文档类资源-CSDN下载qt实现的绘制网络拓补图,先连接sqlserver数据库获取所有节点数据,然后通过递归函数解析出每个更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/weixin_43935474/85868401
qt实现的绘制网络拓补图,先连接sqlserver数据库获取所有节点数据,然后通过递归函数解析出每个节点之间的关系,并计算每个节点要在图上绘制的位置,然后通过重写的
QGraphicsPixmapItem类来绘制节点图,通过重写的
QGraphicsItem类来绘制节点之间的连线。
只要各节点之间的关系数据正确,可以无限绘制。
界面显示如下:
拖动效果如下:
sqlserver数据库表内数据如下:
关键代码如下:
#include <QtWidgets>
#include "nodeframe.h"#include <iostream>
using namespace std;NodeFrame::NodeFrame(QWidget *parent) :QGraphicsView(parent)
{ setGeometry(0,0,1920,2000);m_scene = new QGraphicsScene(0, 0, this->width(), this->height());this->setScene(m_scene);QScrollBar *horBar = this->horizontalScrollBar();QScrollBar *verBar = this->verticalScrollBar();horBar->setValue(horBar->maximum());verBar->setValue(verBar->maximum());
// connectSqlServer();//连接数据库并读取数据,这里先禁用,如果你配好了数据库,则可以开起来manulInitNoteList();//如果不连接数据库则可以手动初始化节点队列,连接数据库的情况下,这行要禁用!initNodeList();
}void NodeFrame::manulInitNoteList()
{NodeInSql node;node.nNodeID =1; node.nParentID =1; node.strNodeName ="根节点"; m_lstNodeInSql.append(node);node.nNodeID =2; node.nParentID =1; node.strNodeName ="子节点2"; m_lstNodeInSql.append(node);node.nNodeID =3; node.nParentID =1; node.strNodeName ="子节点3"; m_lstNodeInSql.append(node);node.nNodeID =4; node.nParentID =1; node.strNodeName ="子节点4"; m_lstNodeInSql.append(node);node.nNodeID =5; node.nParentID =1; node.strNodeName ="子节点5"; m_lstNodeInSql.append(node);node.nNodeID =6; node.nParentID =2; node.strNodeName ="子节点6"; m_lstNodeInSql.append(node);node.nNodeID =7; node.nParentID =2; node.strNodeName ="子节点7"; m_lstNodeInSql.append(node);node.nNodeID =8; node.nParentID =3; node.strNodeName ="子节点8"; m_lstNodeInSql.append(node);node.nNodeID =9; node.nParentID =3; node.strNodeName ="子节点9"; m_lstNodeInSql.append(node);node.nNodeID =10; node.nParentID =4; node.strNodeName ="子节点10"; m_lstNodeInSql.append(node);node.nNodeID =11; node.nParentID =10; node.strNodeName ="子节点11"; m_lstNodeInSql.append(node);node.nNodeID =12; node.nParentID =11; node.strNodeName ="子节点12"; m_lstNodeInSql.append(node);node.nNodeID =13; node.nParentID =12; node.strNodeName ="子节点13"; m_lstNodeInSql.append(node);node.nNodeID =14; node.nParentID =13; node.strNodeName ="子节点14"; m_lstNodeInSql.append(node);node.nNodeID =15; node.nParentID =13; node.strNodeName ="子节点15"; m_lstNodeInSql.append(node);node.nNodeID =16; node.nParentID =13; node.strNodeName ="子节点16"; m_lstNodeInSql.append(node);node.nNodeID =17; node.nParentID =13; node.strNodeName ="子节点17"; m_lstNodeInSql.append(node);node.nNodeID =18; node.nParentID =13; node.strNodeName ="子节点18"; m_lstNodeInSql.append(node);
}
NodeFrame::~NodeFrame()
{delete m_scene;
}void NodeFrame::refresh()
{this->destroyed(m_scene);m_scene = new QGraphicsScene(0, 0, this->width(), this->height());this->setScene(m_scene);initNodeList();
}void NodeFrame::connectSqlServer()
{QSqlDatabase db= QSqlDatabase::addDatabase("QODBC", "dbTemp");db.setDatabaseName(QString("DRIVER={SQL SERVER};""SERVER=%1;" //服务器名称"DATABASE=%2;"//数据库名"UID=%3;" //登录名"PWD=%4;" //密码).arg("127.0.0.1,49674")//我电脑上的端口号是49674.arg("myTestSql").arg("Bruce").arg("Qwerty*963.-+"));//数据库连接bool ok = db.open();if(ok){qDebug()<<"database open success";}else{qDebug()<<db.lastError();return;}//数据库查询QSqlQuery query(db);query.exec("SELECT * FROM Node;");while(query.next()){NodeInSql node;if(query.value(1).isValid())node.nNodeID = query.value(1).toInt();if(query.value(2).isValid())node.nParentID = query.value(2).toInt();if(query.value(3).isValid())node.strNodeName = query.value(3).toString();m_lstNodeInSql.append(node);}db.close();
}void NodeFrame::initNodeList()
{//找到根节点NodeInSql nRootID;foreach(NodeInSql node,m_lstNodeInSql){if(node.nNodeID==node.nParentID){nRootID = node;}}NodeInfoToShow rootNodeInfoToShow;rootNodeInfoToShow.nLevel = 0;rootNodeInfoToShow.nNodeID = nRootID.nNodeID;rootNodeInfoToShow.nParentID = nRootID.nParentID;rootNodeInfoToShow.ptPos = QPoint(0,100);rootNodeInfoToShow.strNodeName = nRootID.strNodeName;m_lstNodeInfoToShow.append(rootNodeInfoToShow);NetNode *rootNetNode = new NetNode(rootNodeInfoToShow,m_scene);parseNodesInSql(rootNodeInfoToShow,rootNetNode);//解析所有节点关系及位置
}
void NodeFrame::parseNodesInSql(NodeInfoToShow node,NetNode *netNode)
{int nChildNum = 0;//当前node节点有几个子节点int nWidth = node.nLevel%2==0?250:150;//节点之间的横向间隔int nHeight = 200;//节点之间的纵向间隔QList<NodeInfoToShow> lstNodeInCrtLevel;//当前node下的所有节点for(int i = 0;i<m_lstNodeInSql.count();i++){if(m_lstNodeInSql[i].nParentID==node.nNodeID && m_lstNodeInSql[i].nParentID!=m_lstNodeInSql[i].nNodeID){nChildNum++;NodeInfoToShow rootNodeInfoToShow;rootNodeInfoToShow.nLevel = node.nLevel+1;rootNodeInfoToShow.nNodeID = m_lstNodeInSql[i].nNodeID;rootNodeInfoToShow.nParentID = node.nNodeID;rootNodeInfoToShow.ptPos = QPoint(0,0);//这里先给0,0点作为初始值,下面再给每个子节点确定位置rootNodeInfoToShow.strNodeName = m_lstNodeInSql[i].strNodeName;lstNodeInCrtLevel.append(rootNodeInfoToShow);}}//确定每个子节点的位置for(int i = 0;i<lstNodeInCrtLevel.count();i++){if(nChildNum%2==1)//有奇数个子节点{int nHalf = (nChildNum-1)/2;int nX =node.ptPos.x()+(i-nHalf)*nWidth;//以上一个节点的x坐标为基础加上偏移量int nY = node.ptPos.y()+nHeight;//以上一个节点的y坐标为基础加上偏移量lstNodeInCrtLevel[i].ptPos = QPoint(nX,nY);}else//有偶数个子节点{int nHalf = nChildNum/2;int nX =node.ptPos.x()+(i-nHalf)*nWidth+nWidth/2;//以上一个节点的x坐标为基础加上偏移量int nY = node.ptPos.y()+nHeight;//以上一个节点的y坐标为基础加上偏移量lstNodeInCrtLevel[i].ptPos = QPoint(nX,nY);}m_lstNodeInfoToShow.append(lstNodeInCrtLevel[i]);NetNode *subNetNode = new NetNode(lstNodeInCrtLevel[i],m_scene);NodeLink *link = new NodeLink(netNode, subNetNode);if (link) {m_scene->addItem(link);}parseNodesInSql(lstNodeInCrtLevel[i],subNetNode);}
}
源码下载连接:
qt绘制网络拓补图(连接数据库,递归函数,无限绘制,可拖动节点)-QT文档类资源-CSDN下载qt实现的绘制网络拓补图,先连接sqlserver数据库获取所有节点数据,然后通过递归函数解析出每个更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/weixin_43935474/85868401
qt绘制网络拓补图(连接数据库,递归函数,无限绘制,可拖动节点)相关推荐
- matlab网络图,Matlab实现网络拓补图
顶点号 顶点号 权值 1 2 400 1 3 450 2 4 300 2 8 230 2 9 140 3 4 600 4 5 210 4 19 310 5 6 230 5 7 200 6 7 320 ...
- 利用prototxt文件绘制网络的结构图
本文转自:http://blog.csdn.net/u014568921/article/details/53947006 如何对prototxt文件绘制网络的结构图 caffe 使能python接口 ...
- Qt下的OpenGL 编程(3)绘制平面几何体
一. 提要 之前的一篇教程已经搭建好了Qt下的OpenGL的编程环境,几天要来学习的就是OpenGL的2D绘图. 2D作为绘图的基础,还是很值得去好好学习,比如迪卡尔坐标,透视设置等等,而所谓的3D, ...
- 绘制网络拓扑图的素材
看看这些对于内容对你绘制网络拓扑图有没有帮助. 转载于:https://blog.51cto.com/403654/84482
- IT-标准化(中国)有限公司-网络拓朴图
看了这么多的文章! 不知道我的网络拓朴图如何! 是我不会画吗? 不是! 是我不会规划吗? 不是! 我想给大家一个完整的画! 你看! 下面正在表演不是吗? IT-标准化-课程-V1.0-系列---所有课 ...
- 利用Visio绘制网络拓扑图要注意些什么
2019独角兽企业重金招聘Python工程师标准>>> 利用Visio绘制网络拓扑图要注意些什么 网络拓扑图绘制工具很多,利用专业的工具可以绘制出漂亮美观的网络拓扑图.下面介绍下网络 ...
- ubuntu下用Qt实现人脸识别之检测人脸并绘制人脸框(三)
ubuntu下用Qt实现人脸识别之检测人脸并绘制人脸框(三) 要检测出人脸并且还要识别出这个人是谁,就得用到人脸算法,这个算法如果你足够牛X的话可以自己写出来,当然,如果像我一样是个小菜鸟的话就得领悟 ...
- 【Qt】2D基本绘图操作——QPainter执行绘制及绘图设备介绍
文章目录 QPainter绘图 绘图设备 QPixmap QImage QPicture Qt实现2D绘图主要基于QPainter.QPaintDevice.QPaintEngine三个类,- - Q ...
- ANTV/G6 绘制网络拓扑图
最近看其他项目绘制网络拓扑图用了vue-super-flow 绘制的不是太理想,所以自己研究了一下,尝试用antv/g6绘制了一下. 参看了官方api https://g6.antv.vision/z ...
最新文章
- Mysql中的DCL
- 怎么区分IP和MAC?子网掩码有何作用?—Vecloud微云
- 顺序表应用4-2:元素位置互换之逆置算法(数据改进)
- larvel mysql count,php – 模型中的Laravel计数函数,然后sortBy count()
- linux系统模块管理
- php sql 二次注入,espcms 二次注入一枚
- 拔得头筹 | 阿里云混合云荣膺IPv6最佳实践奖
- android 点击跳过,android开发里跳过的坑——button不响应点击事件
- Centos7 修改防火墙,开放端口、转发端口
- JAVA中关于set()和get()方法的理解及使用
- CCF201403-5 任务调度(100分题解链接)
- Photoshop 入门教程,处理图层「4」如何向多图层图像中添加更多图像?
- sql server 中join 查詢中on後面 加case的用法.
- 如何搭建短信中心号码服务器,短信中心号码怎么设置?设置短信中心号码两种方法介绍...
- 触摸屏计算机技术参数,触摸屏硬件安装—— 触摸屏参数设置
- 马尔可夫决策过程(Markov Decision Process)学习笔记
- 【FFmpeg】做一个抖音/快手视频模板常用哪些功能
- 前端随机生成验证码vuejsvant~element
- Android手机中获取手机号码和运营商信息
- 编程小白的人工智能路之Gabor滤波提取掌纹特征并对比掌纹相似度(一)
热门文章
- 多媒体个人计算机包括了什么部分,一个完整的多媒体计算机系统,应包含三个组成部分,它们是______。...
- 混乱与秩序2服务器维护,混沌与秩序2救赎世界BOSS刷新位置时间大全
- 大数据笔记--SparkSQL(第一篇)
- 【离散数学】重点、教材及解答
- edX (Global) 介绍
- Level-2行情有什么特色数据
- Linux批量替换sh脚本中\r 符号
- ISO9001质量体系认证办理流程有哪些
- blinker控制步进电机起保停,正反转(Arduino uno+esp8266+TB6600驱动器)
- 现代数字调制及其应用