[gelöst] Elastic Nodes
[gelöst] Elastic Nodes
Ich ändere Trolltech-Beispiel "Elastic Nodes", um eine Simulation zu erstellen:
Elastic Nodes Example
http://doc.trolltech.com/4.2/graphicsvi ... nodes.html
Jetzt versuche ich einen Knoten am Punkt hinzuzufügen, exakt wo der Mauszeiger sich befindet.
Aber ein neuer Knoten wird immer an der unteren-rechten Ecke hinzugefügt,
egal an welcher Position sich der Mauszeiger befindet (besonders wenn das Fenster an der unteren-rechten Ecke liegt).
Also ziehe ich einige Offsets ab (800 von der x-Achse beziehungsweise 600 von der y-Achse),
aber es funktioniert nur wenn sich das Fenster im Vollbildmodus befindet.
Was kann man an meine Code verbessern?
Ich habe nur "graphwidget.h" und "graphwidget.cpp" geändert,
und alle andere Dateien sind unberührt.
Bitte siehe die beiliegende Dateien.
Umwelt:
Qt4.2
Kubuntu 6.10
Jeder Vorschlag ist willkommen.
Elastic Nodes Example
http://doc.trolltech.com/4.2/graphicsvi ... nodes.html
Jetzt versuche ich einen Knoten am Punkt hinzuzufügen, exakt wo der Mauszeiger sich befindet.
Aber ein neuer Knoten wird immer an der unteren-rechten Ecke hinzugefügt,
egal an welcher Position sich der Mauszeiger befindet (besonders wenn das Fenster an der unteren-rechten Ecke liegt).
Also ziehe ich einige Offsets ab (800 von der x-Achse beziehungsweise 600 von der y-Achse),
aber es funktioniert nur wenn sich das Fenster im Vollbildmodus befindet.
Was kann man an meine Code verbessern?
Ich habe nur "graphwidget.h" und "graphwidget.cpp" geändert,
und alle andere Dateien sind unberührt.
Bitte siehe die beiliegende Dateien.
Umwelt:
Qt4.2
Kubuntu 6.10
Jeder Vorschlag ist willkommen.
Zuletzt geändert von einhorn am 10. September 2007 15:14, insgesamt 1-mal geändert.
-
CaptnChaos
- Beiträge: 605
- Registriert: 28. Juni 2007 15:01
- Kontaktdaten:
Schade ...
Upload Error: Kann das Attachment ./files/elasticnodestar_117.gz nicht hochladen.
Hier ist die quellcode:
// graphwidget.cpp
#include "graphwidget.h"
#include "edge.h"
#include "node.h"
#include <QDebug>
#include <QGraphicsScene>
#include <QWheelEvent>
#include <math.h>
/* abs ^ */
#include <QContextMenuEvent>
#include <QMenu>
#include <iostream>
using namespace std;
/* abs v */
GraphWidget::GraphWidget()
: timerId(0)
{
QGraphicsScene *scene = new QGraphicsScene(this);
/* abs ^ */
_scene = scene;
/* abs v */
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
scene->setSceneRect(-200, -200, 400, 400);
setScene(scene);
setCacheMode(CacheBackground);
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);
Node *node2 = new Node(this);
Node *node4 = new Node(this);
centerNode = new Node(this);
Node *node6 = new Node(this);
Node *node8 = new Node(this);
scene->addItem(node2);
scene->addItem(node4);
scene->addItem(centerNode);
scene->addItem(node6);
scene->addItem(node8);
scene->addItem(new Edge(node2, centerNode));
scene->addItem(new Edge(node4, centerNode));
scene->addItem(new Edge(centerNode, node6));
scene->addItem(new Edge(centerNode, node8));
node2->setPos(0, -50);
node4->setPos(-50, 0);
centerNode->setPos(0, 0);
node6->setPos(50, 0);
node8->setPos(0, 50);
/* abs ^ */
// initialization
numNode = 0;
nodeX = new QVector<Node*>();
for(int i=0; i<numNode; i++)
{
nodeX->append( new Node( this ) );
scene->addItem( nodeX->at(i) );
scene->addItem(new Edge(centerNode, nodeX->at(i)));
nodeX->at(i)->setPos(50+(i*2), 50+(i*2));
}
/* abs ^ */
// scale(0.8, 0.8);
scale(1.0, 1.0);
setMinimumSize(400, 400);
setWindowTitle(tr("Elastic Nodes"));
}
/* abs ^ */
QGraphicsScene *GraphWidget::scene()
{
return _scene;
} // scene()
void GraphWidget::contextMenuEvent( QContextMenuEvent *ev )
{
if ( itemAt( ev->pos() ) )
{
QGraphicsView::contextMenuEvent( ev );
}
else
{
QMenu contextMenu;
QAction *addNodeAction = contextMenu.addAction( QObject::tr( "Add Node" ) );
connect( addNodeAction, SIGNAL( triggered() ), this, SLOT( addNode() ) );
contextMenu.exec( ev->globalPos() );
}
}; // contextMenuEvent( QContextMenuEvent* )
void GraphWidget::addNode()
{
int i=0; // this is just a temporal value
nodeX = new QVector<Node*>();
nodeX->append( new Node( this ) );
scene()->addItem( nodeX->at(i) );
// scene()->addItem(new Edge(centerNode, nodeX->at(i)));
// nodeX->at(i)->setPos(50+(i*2), 50+(i*2));
// nodeX->at(i)->setPos( mapFromGlobal (QCursor::pos() ) );
// nodeX->at(i)->setPos( (QCursor::pos()).x(), (QCursor::pos()).y() );
nodeX->at(i)->setPos( (QCursor::pos()).x()-800, (QCursor::pos()).y()-600 );
} // addNode()
void GraphWidget::mousePressEvent( QMouseEvent * ev )
{
if ( ev->modifiers() & Qt::ControlModifier )
{
setDragMode( QGraphicsView::RubberBandDrag );
}
QGraphicsView::mousePressEvent( ev );
}; // mousePressEvent( QMouseEvent* )
void GraphWidget::mouseReleaseEvent( QMouseEvent * ev )
{
QGraphicsView::mouseReleaseEvent( ev );
setDragMode( QGraphicsView::ScrollHandDrag );
}; // mouseReleaseEvent( QMouseEvent* )
/* abs v */
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:
scaleView(1.2);
break;
case Qt::Key_Minus:
scaleView(1 / 1.2);
break;
case Qt::Key_Space:
case Qt::Key_Enter:
foreach (QGraphicsItem *item, scene()->items()) {
if (qgraphicsitem_cast<Node *>(item))
item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
}
break;
default:
QGraphicsView::keyPressEvent(event);
}
}
void GraphWidget::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
QList<Node *> nodes;
foreach (QGraphicsItem *item, scene()->items()) {
if (Node *node = qgraphicsitem_cast<Node *>(item))
nodes << node;
}
foreach (Node *node, nodes)
node->calculateForces();
bool itemsMoved = false;
foreach (Node *node, nodes) {
if (node->advance())
itemsMoved = true;
}
if (!itemsMoved) {
killTimer(timerId);
timerId = 0;
}
}
void GraphWidget::wheelEvent(QWheelEvent *event)
{
scaleView(pow((double)2, -event->delta() / 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.intersect(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("Click and drag the nodes around, and zoom with the mouse "
"wheel or the '+' and '-' keys"));
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 = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.07 || factor > 100)
return;
scale(scaleFactor, scaleFactor);
}
Upload Error: Kann das Attachment ./files/elasticnodestar_117.gz nicht hochladen.
Hier ist die quellcode:
// graphwidget.cpp
#include "graphwidget.h"
#include "edge.h"
#include "node.h"
#include <QDebug>
#include <QGraphicsScene>
#include <QWheelEvent>
#include <math.h>
/* abs ^ */
#include <QContextMenuEvent>
#include <QMenu>
#include <iostream>
using namespace std;
/* abs v */
GraphWidget::GraphWidget()
: timerId(0)
{
QGraphicsScene *scene = new QGraphicsScene(this);
/* abs ^ */
_scene = scene;
/* abs v */
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
scene->setSceneRect(-200, -200, 400, 400);
setScene(scene);
setCacheMode(CacheBackground);
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);
Node *node2 = new Node(this);
Node *node4 = new Node(this);
centerNode = new Node(this);
Node *node6 = new Node(this);
Node *node8 = new Node(this);
scene->addItem(node2);
scene->addItem(node4);
scene->addItem(centerNode);
scene->addItem(node6);
scene->addItem(node8);
scene->addItem(new Edge(node2, centerNode));
scene->addItem(new Edge(node4, centerNode));
scene->addItem(new Edge(centerNode, node6));
scene->addItem(new Edge(centerNode, node8));
node2->setPos(0, -50);
node4->setPos(-50, 0);
centerNode->setPos(0, 0);
node6->setPos(50, 0);
node8->setPos(0, 50);
/* abs ^ */
// initialization
numNode = 0;
nodeX = new QVector<Node*>();
for(int i=0; i<numNode; i++)
{
nodeX->append( new Node( this ) );
scene->addItem( nodeX->at(i) );
scene->addItem(new Edge(centerNode, nodeX->at(i)));
nodeX->at(i)->setPos(50+(i*2), 50+(i*2));
}
/* abs ^ */
// scale(0.8, 0.8);
scale(1.0, 1.0);
setMinimumSize(400, 400);
setWindowTitle(tr("Elastic Nodes"));
}
/* abs ^ */
QGraphicsScene *GraphWidget::scene()
{
return _scene;
} // scene()
void GraphWidget::contextMenuEvent( QContextMenuEvent *ev )
{
if ( itemAt( ev->pos() ) )
{
QGraphicsView::contextMenuEvent( ev );
}
else
{
QMenu contextMenu;
QAction *addNodeAction = contextMenu.addAction( QObject::tr( "Add Node" ) );
connect( addNodeAction, SIGNAL( triggered() ), this, SLOT( addNode() ) );
contextMenu.exec( ev->globalPos() );
}
}; // contextMenuEvent( QContextMenuEvent* )
void GraphWidget::addNode()
{
int i=0; // this is just a temporal value
nodeX = new QVector<Node*>();
nodeX->append( new Node( this ) );
scene()->addItem( nodeX->at(i) );
// scene()->addItem(new Edge(centerNode, nodeX->at(i)));
// nodeX->at(i)->setPos(50+(i*2), 50+(i*2));
// nodeX->at(i)->setPos( mapFromGlobal (QCursor::pos() ) );
// nodeX->at(i)->setPos( (QCursor::pos()).x(), (QCursor::pos()).y() );
nodeX->at(i)->setPos( (QCursor::pos()).x()-800, (QCursor::pos()).y()-600 );
} // addNode()
void GraphWidget::mousePressEvent( QMouseEvent * ev )
{
if ( ev->modifiers() & Qt::ControlModifier )
{
setDragMode( QGraphicsView::RubberBandDrag );
}
QGraphicsView::mousePressEvent( ev );
}; // mousePressEvent( QMouseEvent* )
void GraphWidget::mouseReleaseEvent( QMouseEvent * ev )
{
QGraphicsView::mouseReleaseEvent( ev );
setDragMode( QGraphicsView::ScrollHandDrag );
}; // mouseReleaseEvent( QMouseEvent* )
/* abs v */
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:
scaleView(1.2);
break;
case Qt::Key_Minus:
scaleView(1 / 1.2);
break;
case Qt::Key_Space:
case Qt::Key_Enter:
foreach (QGraphicsItem *item, scene()->items()) {
if (qgraphicsitem_cast<Node *>(item))
item->setPos(-150 + qrand() % 300, -150 + qrand() % 300);
}
break;
default:
QGraphicsView::keyPressEvent(event);
}
}
void GraphWidget::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
QList<Node *> nodes;
foreach (QGraphicsItem *item, scene()->items()) {
if (Node *node = qgraphicsitem_cast<Node *>(item))
nodes << node;
}
foreach (Node *node, nodes)
node->calculateForces();
bool itemsMoved = false;
foreach (Node *node, nodes) {
if (node->advance())
itemsMoved = true;
}
if (!itemsMoved) {
killTimer(timerId);
timerId = 0;
}
}
void GraphWidget::wheelEvent(QWheelEvent *event)
{
scaleView(pow((double)2, -event->delta() / 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.intersect(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("Click and drag the nodes around, and zoom with the mouse "
"wheel or the '+' and '-' keys"));
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 = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.07 || factor > 100)
return;
scale(scaleFactor, scaleFactor);
}
Hier ist die andere Quellcode:
// graphwidget.h
#ifndef GRAPHWIDGET_H
#define GRAPHWIDGET_H
#include <QtGui/QGraphicsView>
/* abs ^ */
#include <QVector>
/* abs v */
class Node;
/* abs ^ */
class QContextMenuEvent;
/* abs v */
class GraphWidget : public QGraphicsView
{
Q_OBJECT
public:
GraphWidget();
void itemMoved();
/* abs ^ */
void contextMenuEvent( QContextMenuEvent *ev );
void mouseReleaseEvent( QMouseEvent * ev );
void mousePressEvent( QMouseEvent * ev );
QGraphicsScene *scene();
public slots:
void addNode();
// void addNode( QContextMenuEvent *ev );
/* abs v */
protected:
void keyPressEvent(QKeyEvent *event);
void timerEvent(QTimerEvent *event);
void wheelEvent(QWheelEvent *event);
void drawBackground(QPainter *painter, const QRectF &rect);
void scaleView(qreal scaleFactor);
private:
int timerId;
Node *centerNode;
/* abs ^ */
int numNode;
QVector<Node*> *nodeX;
QGraphicsScene *_scene;
/* abs v */
};
#endif
// graphwidget.h
#ifndef GRAPHWIDGET_H
#define GRAPHWIDGET_H
#include <QtGui/QGraphicsView>
/* abs ^ */
#include <QVector>
/* abs v */
class Node;
/* abs ^ */
class QContextMenuEvent;
/* abs v */
class GraphWidget : public QGraphicsView
{
Q_OBJECT
public:
GraphWidget();
void itemMoved();
/* abs ^ */
void contextMenuEvent( QContextMenuEvent *ev );
void mouseReleaseEvent( QMouseEvent * ev );
void mousePressEvent( QMouseEvent * ev );
QGraphicsScene *scene();
public slots:
void addNode();
// void addNode( QContextMenuEvent *ev );
/* abs v */
protected:
void keyPressEvent(QKeyEvent *event);
void timerEvent(QTimerEvent *event);
void wheelEvent(QWheelEvent *event);
void drawBackground(QPainter *painter, const QRectF &rect);
void scaleView(qreal scaleFactor);
private:
int timerId;
Node *centerNode;
/* abs ^ */
int numNode;
QVector<Node*> *nodeX;
QGraphicsScene *_scene;
/* abs v */
};
#endif
-
CaptnChaos
- Beiträge: 605
- Registriert: 28. Juni 2007 15:01
- Kontaktdaten:
HNGH!
menno... ich will ja net wieder motzen, aber das nächste mal setzt du quellcode in die eigens dafür entwickelte umgebung, ok?
ich schau mir das mal an übers wochenende, vllt kann ich heut abend auch schon was dazu sagen.
menno... ich will ja net wieder motzen, aber das nächste mal setzt du quellcode in die eigens dafür entwickelte
Code: Alles auswählen
codeich schau mir das mal an übers wochenende, vllt kann ich heut abend auch schon was dazu sagen.
Code: Alles auswählen
void test()
{
printf("Ja, ich bin einverstanden. Ich mache das nächste mal. Danke schön!\n");
}
[gelöst] Elastic Nodes
KernelPanic hat mir die Lösung geschickt
und sie funktioniert perfekt!
Im Fall jemand das gleiche Problem hat,
füge ich hier ein, was er an meine Code verbessert hat.
In graphwidget.h:
In graphwidget.cpp:
Vielen Dank, KernelPanic!
und sie funktioniert perfekt!
Im Fall jemand das gleiche Problem hat,
füge ich hier ein, was er an meine Code verbessert hat.
In graphwidget.h:
Code: Alles auswählen
private:
QPoint addNodePoint; //rechtsklickposition
Code: Alles auswählen
void GraphWidget::contextMenuEvent( QContextMenuEvent *ev )
{
if ( itemAt( ev->pos() ) )
{
QGraphicsView::contextMenuEvent( ev );
}
else
{
QMenu contextMenu;
QAction *addNodeAction = contextMenu.addAction( QObject::tr( "Add Node" ) );
connect( addNodeAction, SIGNAL( triggered() ), this, SLOT( addNode() ) );
addNodePoint = ev->pos();
contextMenu.exec( ev->globalPos() );
}
}; // contextMenuEvent( QContextMenuEvent* )
void GraphWidget::addNode()
{
int i=0; // this is just a temporal value
nodeX = new QVector<Node*>();
nodeX->append( new Node( this ) );
scene()->addItem( nodeX->at(i) );
nodeX->at(i)->setPos( mapToScene (addNodePoint) );
} // addNode()