PDA

View Full Version : Help implementing graphics classes



tfarmer4
27th July 2010, 00:41
I have the files that I have posted below. My question is, how do I begin building my graph in the QGraphicsScene? I'm just really confused on how to place nodes and links on the scene to be visualized. I'm very new to QT and am working on a graph project for computer science. Here is all my code:



//link.h
class Node;
#ifndef LINK_H
#define LINK_H
#include "diagramwindow.h"
#include "Node.h"

using namespace Qt;

class Link : public QGraphicsLineItem{
public:
Link(Node *fromNode, Node *toNode){
myFromNode = fromNode;
myToNode = toNode;

myFromNode->addLink(this);
myToNode->addLink(this);

setColor(Qt::black);
}
~Link(){
myFromNode->removeLink(this);
myToNode->removeLink(this);
}

void setColor(const QColor &color){
setPen(QPen(color,1.0));
}
QColor color()const;

void trackNodes(){
setLine(QLineF(myFromNode->pos(), myToNode->pos()));
}

private:
Node *myFromNode;
Node *myToNode;
};
#endif // LINK_H



//Node.h
#ifndef NODE_H
#define NODE_H
#include <QGraphicsItem>
#include "Link.h"
#include <QFontMetricsF>
#include <QSet>
#include <QString>
#include <QRectF>
#include <QApplication>
using namespace Qt;
class Link;
class Node : public QGraphicsItem{

public:
Node(){
myTextColor = Qt::black;
myOutlineColor = Qt::black;
myBackgroundColor = Qt::white;
}

void setText(const QString &text){
prepareGeometryChange();
myText = text;
update();
}
void setTextColor(const QColor &color){
myTextColor = color;
update();
}
void addLink(Link *link){
myLinks.insert(link);
}
void removeLink(Link *link){
myLinks.remove(link);
}
QRectF outlineRect()const{
const int Padding = 8;
QFontMetricsF metrics = qApp->font();
QRectF rect = metrics.boundingRect(myText);
rect.adjust(-Padding, -Padding, +Padding, +Padding);
rect.translate(-rect.center());
return rect;
}
QRectF boundingRect()const{
const int Margin = 1;
return outlineRect().adjusted(-Margin, -Margin, +Margin, +Margin);
}
QPainterPath shape()const{
QRectF rect = outlineRect();

QPainterPath path;
path.addRoundRect(rect, roundness(rect.width()),
roundness(rect.height()));
return path;
}
void paint(QPainter *painter,
QWidget * /* widget*/){
QPen pen(myOutlineColor);
painter->setPen(pen);
painter->setBrush(myBackgroundColor);

QRectF rect = outlineRect();
painter->drawRoundRect(rect, roundness(rect.width()),
roundness(rect.height()));
painter->setPen(myTextColor);
painter->drawText(rect, Qt::AlignCenter, myText);
}
private:
int roundness(double size)const{
const int DIAMETER = 12;
return 100*DIAMETER/int(size);
}

QSet<Link*>myLinks;
QString myText;
QColor myBackgroundColor;
QColor myOutlineColor;
QColor myTextColor;
};
#endif // NODE_H



//diagramwindow.h
#ifndef DIAGRAMWINDOW_H
#define DIAGRAMWINDOW_H
#include <QObject>
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include "Link.h"
class Node;
class List;
namespace Ui {
class DiagramWindow;
}

class DiagramWindow : public QMainWindow
{
Q_OBJECT

public:
explicit DiagramWindow();
~DiagramWindow();
private slots:
void addNode(){
Node *node;
node->setText(QObject::tr("Node %1").arg(seqNumber +1));
setupNode(node);
}

void addLink(Node *nodeA, Node *nodeB);

private:
Ui::DiagramWindow *ui;
QGraphicsScene *scene;
QGraphicsView *view;
int minZ;
int maxZ;
int seqNumber;
void setupNode(Node *node){
node->setPos(QPoint(80+ (100 * (seqNumber % 5)), (80+ (50 * ((seqNumber/5)%7)))));
scene->addItem(node);
++seqNumber;
}
};

#endif // DIAGRAMWINDOW_H



//diagramwindow.cpp
#include "diagramwindow.h"
#include "ui_diagramwindow.h"
#include "Node.h"
#include "Link.h"

void DiagramWindow::addLink(Node *nodeA, Node *nodeB){
Link *link = new Link(nodeA, nodeB);
scene->addItem(link);
}
DiagramWindow::DiagramWindow() :
QMainWindow(),
ui(new Ui::DiagramWindow)
{
DiagramWindow window;

scene = new QGraphicsScene(0,0,600,500);

view = new QGraphicsView;
view->setScene(scene);
view->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
view->setContextMenuPolicy(Qt::ActionsContextMenu);
setCentralWidget(view);
minZ = 0;
maxZ = 0;
seqNumber = 0;
setWindowTitle("Proteins Diagram");

ui->setupUi(this);
window.addNode();
}

DiagramWindow::~DiagramWindow()
{
delete ui;
}



//main.cpp
#include <QtGui/QApplication>
#include "diagramwindow.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DiagramWindow w;
w.show();
w.update();
return a.exec();
}

Thanks for all your help. I understand how to write these class, as you can see I wrote these, I'm just confused on how to put it all on the scene, or whatever I need to do.

tbscope
27th July 2010, 05:29
Node *node;
node->setText(QObject::tr("Node %1").arg(seqNumber +1));

This is wrong and will crash. You need to initialise node first.
Node *node = new Node;

ChrisW67
27th July 2010, 05:41
Your classes bear more than a passing resemblance to those in C+ GUI Programming with Qt4:
http://www.informit.com/articles/article.aspx?p=1174421&seqNum=4

Your QGraphicsView should be part of the Designer UI, or you should abandon the Designer UI. As it stands you are creating a QGraphicsView, setting it as the central widget of your main window, and then trashing it with the Designer UI (through setupUi() in diagramwindow.cpp).

tfarmer4
28th July 2010, 20:32
Node *node;
node->setText(QObject::tr("Node %1").arg(seqNumber +1));

This is wrong and will crash. You need to initialise node first.
Node *node = new Node;

If i try to initialize *node, I get an error that says invalid use of incomplete type Node.

Zlatomir
28th July 2010, 21:11
If i try to initialize *node, I get an error that says invalid use of incomplete type Node.
That is because in that header file you have only a forward declaration of class Node, move the definition of addNode() in the cpp file (diagramwindow.cpp) in there you have included the Node.h, so you can create objects, because the compiler knows how your objects look like.

tfarmer4
28th July 2010, 21:15
Your QGraphicsView should be part of the Designer UI, or you should abandon the Designer UI. As it stands you are creating a QGraphicsView, setting it as the central widget of your main window, and then trashing it with the Designer UI (through setupUi() in diagramwindow.cpp).

Ok, I see. So how would I make QGraphicsView part of the Designer UI?

ChrisW67
29th July 2010, 00:01
So how would I make QGraphicsView part of the Designer UI?
Just like any other widget. Open the UI file in Designer then drag a QGraphicsView from the "Display Widgets" group onto the layout, name it, save and build. You will need to adjust your code to use the QGraphicsView generated for you rather than creating it yourself.