当前位置:网站首页>QT drawing network topology diagram (connecting database, recursive function, infinite drawing, dragging nodes)
QT drawing network topology diagram (connecting database, recursive function, infinite drawing, dragging nodes)
2022-07-04 23:07:00 【GreenHandBruce】
Hardware :ThinkPadT590
System :Win10
database :sqlserver2014
Qt:5.14.1
QtCreator:4.11.1
Source connection :
qt To achieve the drawing of network topology diagram , Connect first sqlserver The database obtains all node data , Then the relationship between each node is resolved by recursive function , And calculate the position of each node to be drawn on the graph , Then by rewriting
QGraphicsPixmapItem Class to draw a node graph , By rewriting
QGraphicsItem Class to draw the line between nodes .
As long as the relationship data between nodes is correct , You can draw infinitely .
The interface is as follows :
The dragging effect is as follows :
sqlserver The data in the database table is as follows :
The key codes are as follows :
#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();// Connect to the database and read the data , Disable here first , If you have a good database , You can drive
manulInitNoteList();// If you do not connect to the database, you can manually initialize the node queue , When connecting to the database , This line should be disabled !
initNodeList();
}
void NodeFrame::manulInitNoteList()
{
NodeInSql node;
node.nNodeID =1; node.nParentID =1; node.strNodeName =" The root node "; m_lstNodeInSql.append(node);
node.nNodeID =2; node.nParentID =1; node.strNodeName =" Child node 2"; m_lstNodeInSql.append(node);
node.nNodeID =3; node.nParentID =1; node.strNodeName =" Child node 3"; m_lstNodeInSql.append(node);
node.nNodeID =4; node.nParentID =1; node.strNodeName =" Child node 4"; m_lstNodeInSql.append(node);
node.nNodeID =5; node.nParentID =1; node.strNodeName =" Child node 5"; m_lstNodeInSql.append(node);
node.nNodeID =6; node.nParentID =2; node.strNodeName =" Child node 6"; m_lstNodeInSql.append(node);
node.nNodeID =7; node.nParentID =2; node.strNodeName =" Child node 7"; m_lstNodeInSql.append(node);
node.nNodeID =8; node.nParentID =3; node.strNodeName =" Child node 8"; m_lstNodeInSql.append(node);
node.nNodeID =9; node.nParentID =3; node.strNodeName =" Child node 9"; m_lstNodeInSql.append(node);
node.nNodeID =10; node.nParentID =4; node.strNodeName =" Child node 10"; m_lstNodeInSql.append(node);
node.nNodeID =11; node.nParentID =10; node.strNodeName =" Child node 11"; m_lstNodeInSql.append(node);
node.nNodeID =12; node.nParentID =11; node.strNodeName =" Child node 12"; m_lstNodeInSql.append(node);
node.nNodeID =13; node.nParentID =12; node.strNodeName =" Child node 13"; m_lstNodeInSql.append(node);
node.nNodeID =14; node.nParentID =13; node.strNodeName =" Child node 14"; m_lstNodeInSql.append(node);
node.nNodeID =15; node.nParentID =13; node.strNodeName =" Child node 15"; m_lstNodeInSql.append(node);
node.nNodeID =16; node.nParentID =13; node.strNodeName =" Child node 16"; m_lstNodeInSql.append(node);
node.nNodeID =17; node.nParentID =13; node.strNodeName =" Child node 17"; m_lstNodeInSql.append(node);
node.nNodeID =18; node.nParentID =13; node.strNodeName =" Child node 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;" // Server name
"DATABASE=%2;"// Database name
"UID=%3;" // Login name
"PWD=%4;" // password
).arg("127.0.0.1,49674")// The port number on my computer is 49674
.arg("myTestSql")
.arg("Bruce")
.arg("Qwerty*963.-+")
);
// Database connection
bool ok = db.open();
if(ok)
{
qDebug()<<"database open success";
}
else
{
qDebug()<<db.lastError();
return;
}
// Database query
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()
{
// Find the root node
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);// Analyze all node relationships and locations
}
void NodeFrame::parseNodesInSql(NodeInfoToShow node,NetNode *netNode)
{
int nChildNum = 0;// At present node A node has several child nodes
int nWidth = node.nLevel%2==0?250:150;// Horizontal spacing between nodes
int nHeight = 200;// Longitudinal spacing between nodes
QList<NodeInfoToShow> lstNodeInCrtLevel;// At present node All nodes under
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);// Here first 0,0 Point as initial value , Next, determine the location of each child node
rootNodeInfoToShow.strNodeName = m_lstNodeInSql[i].strNodeName;
lstNodeInCrtLevel.append(rootNodeInfoToShow);
}
}
// Determine the location of each child node
for(int i = 0;i<lstNodeInCrtLevel.count();i++)
{
if(nChildNum%2==1)// There are odd child nodes
{
int nHalf = (nChildNum-1)/2;
int nX =node.ptPos.x()+(i-nHalf)*nWidth;// Of the above node x Based on coordinates plus offset
int nY = node.ptPos.y()+nHeight;// Of the above node y Based on coordinates plus offset
lstNodeInCrtLevel[i].ptPos = QPoint(nX,nY);
}
else// There are even child nodes
{
int nHalf = nChildNum/2;
int nX =node.ptPos.x()+(i-nHalf)*nWidth+nWidth/2;// Of the above node x Based on coordinates plus offset
int nY = node.ptPos.y()+nHeight;// Of the above node y Based on coordinates plus offset
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);
}
}
Source download connection :
边栏推荐
- 位运算符讲解
- 剑指 Offer 65. 不用加减乘除做加法
- A complete tutorial for getting started with redis: Pipeline
- 【ODX Studio编辑PDX】-0.2-如何对比Compare两个PDX/ODX文件
- The difference between Max and greatest in SQL
- Analysis of the self increasing and self decreasing of C language function parameters
- [roommate learned to use Bi report data processing in the time of King glory in one game]
- The small program vant tab component solves the problem of too much text and incomplete display
- MariaDB的Galera集群应用场景--数据库多主多活
- qt绘制网络拓补图(连接数据库,递归函数,无限绘制,可拖动节点)
猜你喜欢
colResizable. JS auto adjust table width plug-in
SPH中的粒子初始排列问题(两张图解决)
SHP data making 3dfiles white film
P2181 diagonal and p1030 [noip2001 popularization group] arrange in order
Persistence mechanism of redis
攻防世界 MISC 进阶区 3-11
[sword finger offer] questions 1-5
PS style JS webpage graffiti board plug-in
heatmap. JS picture hotspot heat map plug-in
Advanced area a of attack and defense world misc Masters_ good_ idea
随机推荐
Analog rocker controlled steering gear
时间 (计算)总工具类 例子: 今年开始时间和今年结束时间等
Redis入门完整教程:Redis Shell
为什么信息图会帮助你的SEO
Redis入门完整教程:集合详解
Redis getting started complete tutorial: Geo
Sobel filter
Insert sort, select sort, bubble sort
SHP data making 3dfiles white film
攻防世界 MISC 进阶区 can_has_stdio?
机器学习在房屋价格预测上的应用
The difference between Max and greatest in SQL
[machine learning] handwritten digit recognition
Attack and defense world misc master advanced zone 001 normal_ png
Attack and defense world misc advanced zone 2017_ Dating_ in_ Singapore
JS 3D explosive fragment image switching JS special effect
Redis入门完整教程:键管理
Create Ca and issue certificate through go language
该如何去选择证券公司,手机上开户安不安全
[roommate learned to use Bi report data processing in the time of King glory in one game]