#include "graphwidget.h"
#include "edge.h"
#include "node.h"
#include <math.h>
#include <QKeyEvent>
#include <QRandomGenerator>
GraphWidget::GraphWidget(QWidget *parent,int node_number, QSize size)
: QGraphicsView(parent)
{
myscene = new QGraphicsScene(this);
myscene->setItemIndexMethod(QGraphicsScene::NoIndex);
myscene->setSceneRect(-200, -200, 400, 400);
setScene(myscene);
setCacheMode(CacheBackground);
setViewportUpdateMode(BoundingRectViewportUpdate);
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
scale(qreal(1), qreal(1));
setMinimumSize(400, 400);
setWindowTitle(tr("Elastic Nodes"));
m_node_number = node_number>10?10:node_number; //不能超过10个节点
m_size = size;
is_waitlink = false;
for(int i = 0;i<m_node_number;i++)
{
node[i] = new Node(this,i,m_size);
myscene->addItem(node[i]);
}
}
void GraphWidget::setNodeNumber(int node_number)
{
m_node_number = node_number>10?10:node_number; //不能超过10个节点
myscene->clear();
for(int i = 0;i<m_node_number;i++)
{
node[i] = new Node(this,i,m_size);
myscene->addItem(node[i]);
}
//删除节点间连线
for(int i = 0;i<10;i++)
{
for(int j = 0;j<10;j++)
{
edge[i][j] = NULL;
}
}
}
void GraphWidget::itemMoved()
{
if (!timerId)
timerId = startTimer(1000 / 25);
}
void GraphWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Up:
centerNode->moveBy(0, -20);
break;
case Qt::Key_Down:
centerNode->moveBy(0, 20);
break;
case Qt::Key_Left:
centerNode->moveBy(-20, 0);
break;
case Qt::Key_Right:
centerNode->moveBy(20, 0);
break;
case Qt::Key_Plus:
zoomIn();
break;
case Qt::Key_Minus:
zoomOut();
break;
case Qt::Key_Space:
case Qt::Key_Enter:
shuffle();
break;
default:
QGraphicsView::keyPressEvent(event);
}
}
void GraphWidget::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
QVector<Node *> nodes;
const QList<QGraphicsItem *> items = scene()->items();
for (QGraphicsItem *item : items) {
if (Node *node = qgraphicsitem_cast<Node *>(item))
nodes << node;
}
for (Node *node : qAsConst(nodes))
node->calculateForces();
bool itemsMoved = false;
for (Node *node : qAsConst(nodes)) {
if (node->advancePosition())
itemsMoved = true;
}
if (!itemsMoved) {
killTimer(timerId);
timerId = 0;
}
}
void GraphWidget::choosenode(int node_id)
{
if(is_waitlink == false) //记录第一个点
{
firstnode = node_id;
node[firstnode]->setchoosed(true);
node[firstnode]->update();
is_waitlink = true;
}
else //判断和第一个点的关系
{
node[firstnode]->setchoosed(false); //不起作用
node[firstnode]->update(); //需要加上这一句
if(node_id != firstnode)
{
//int maxid = qMax(node_id,firstnode);
//int minid = qMin(node_id,firstnode);
//int edge_id = (18-minid)*(minid+1)/2+maxid-10;
if(!edge[firstnode][node_id]) //指针需要初始化,野指针和空指针的区别
{
edge[firstnode][node_id] = new Edge(node[firstnode], node[node_id]);
myscene->addItem(edge[firstnode][node_id]);
}
else
{
myscene->removeItem(edge[firstnode][node_id]);
edge[firstnode][node_id] = NULL;
node[firstnode]->setchoosed(false);
}
}
is_waitlink = false;
}
}
void GraphWidget::addEdge(int firstnode,int node_id)
{
edge[firstnode][node_id] = new Edge(node[firstnode], node[node_id]);
myscene->addItem(edge[firstnode][node_id]);
}
void GraphWidget::wheelEvent(QWheelEvent *event)
{
scaleView(pow(2., -event->angleDelta().y() / 240.0));
}
void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
Q_UNUSED(rect);
// // Shadow
// QRectF sceneRect = this->sceneRect();
// QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
// QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
// if (rightShadow.intersects(rect) || rightShadow.contains(rect))
// painter->fillRect(rightShadow, Qt::darkGray);
// if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
// painter->fillRect(bottomShadow, Qt::darkGray);
// // Fill
// QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
// gradient.setColorAt(0, Qt::white);
// gradient.setColorAt(1, Qt::lightGray);
// painter->fillRect(rect.intersected(sceneRect), gradient);
// painter->setBrush(Qt::NoBrush);
// painter->drawRect(sceneRect);
// // Text
// QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4,
// sceneRect.width() - 4, sceneRect.height() - 4);
// QString message(tr("Please select two nodes to connect"));
// QFont font = painter->font();
// font.setBold(true);
// font.setPointSize(14);
// painter->setFont(font);
// painter->setPen(Qt::lightGray);
// painter->drawText(textRect.translated(2, 2), message);
// painter->setPen(Qt::black);
// painter->drawText(textRect, message);
}
void GraphWidget::scaleView(qreal scaleFactor)
{
qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.07 || factor > 100)
return;
scale(scaleFactor, scaleFactor);
}
void GraphWidget::shuffle()
{
const QList<QGraphicsItem *> items = scene()->items();
for (QGraphicsItem *item : items) {
if (qgraphicsitem_cast<Node *>(item))
item->setPos(-150 + QRandomGenerator::global()->bounded(300), -150 + QRandomGenerator::global()->bounded(300));
}
}
void GraphWidget::zoomIn()
{
scaleView(qreal(1.2));
}
void GraphWidget::zoomOut()
{
scaleView(1 / qreal(1.2));
}
QFCTopologyInput.rar
需积分: 46 62 浏览量
2020-06-27
08:06:16
上传
评论 7
收藏 6KB RAR 举报
仟人斩
- 粉丝: 4805
- 资源: 37
最新资源
- mybatis中的动态sql, 涉及 where trim set if foreach等
- 简单- 快递运输(Java & JS & Python & C).html
- mybatis框架 更改ems系统,使用动态sql等.zip
- 易语言工具条下拉菜单实现
- Mybatis动态SQL高级映射.zip
- 源码esp8266开发板机智云机智云智能灯
- Python实现多图像转换成连贯的PDF文件,支持所有图片格式,可预览、裁剪、自定义PDF布局、设置图像顺序、PDF质量选择等
- H5腾讯地图选择位置组件
- 基于UCC28019+LM5017电源板硬件(原理图+PCB)工程文件.zip
- 源码esp8266开发板机智云机智云空气净化器
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈