PDA

View Full Version : QGraphics Item custom class not compiling



budda
21st April 2010, 01:12
So it was 7 am and I had been up all night, and in frustration I posted a thread in a not very awake state.... I've re-looked at the problem and it is much easier to explain than my up for 40 hours, fried explanation. I have a mainwindow program that I am working on. It does almost everything through QGraphicsScenes/Views at one point I want to load a bunch of items from a custom QGraphicsItem class.... node.h node.cpp I wrote modified the node class from the elasticnodes demo program... because everytime I write my own class, it is not interacting with the mainwindow correctly and not compiling... so I've been stripping down the example and I have my class working with the example, but re-implementing the class from the example to my code is trying more than my patience... I am under time limits and am very pressed for time. The 'working' part I am posting here is the stripped example and is just drawing a simple 2 lines. it is much more intensive actually as I have all 256 ascii characters as quick little drawLine routines....

http://www.baskanos.com/avabiwskomai/classScreenShot.png

main.cpp

#include <QtGui>

#include "graphwidget.h"

int main(int argc, char **argv)
{
QApplication app(argc, argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

GraphWidget widget;
widget.show();
return app.exec();
}


the class I'm trying to divorce from the next class

graphwidget.h


#ifndef GRAPHWIDGET_H
#define GRAPHWIDGET_H

#include <QtGui/QGraphicsView>

class Node;

class GraphWidget : public QGraphicsView
{
Q_OBJECT

public:
GraphWidget();

void itemMoved();

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;

};

#endif


graphwidget.cpp


#include "graphwidget.h"
#include "node.h"

#include <QDebug>
#include <QGraphicsScene>
#include <QWheelEvent>

#include <math.h>

GraphWidget::GraphWidget()
: timerId(0)
{
QGraphicsScene *scene = new QGraphicsScene(this);
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
scene->setSceneRect(-200, -200, 400, 400);
setScene(scene);
setCacheMode(CacheBackground);
setViewportUpdateMode(BoundingRectViewportUpdate);
// setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);

int px = -100; int py = -100;

for (int i = 0; i < 256; i++)
{

if (px < 148) px+=8;
else { px = -100; py+=16; }

}


scale(qreal(1.0), qreal(1.0));
setMinimumSize(400, 400);
// setWindowTitle(tr("Elastic Nodes"));
}

void GraphWidget::itemMoved()
{
if (!timerId)
timerId = startTimer(1000 / 25);
}

void GraphWidget::keyPressEvent(QKeyEvent *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;
}




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);


// painter->fillRect(rect.intersect(sceneRect), gradient);
painter->setBrush(Qt::NoBrush);
painter->setBrush(QBrush(Qt::black));
painter->drawRect(sceneRect);


}

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);
}


class I'm trying to get out of this

node.h


#ifndef NODE_H
#define NODE_H

#include <QGraphicsItem>
#include <QList>


class GraphWidget;
QT_BEGIN_NAMESPACE
class QGraphicsSceneMouseEvent;
QT_END_NAMESPACE

class Node : public QGraphicsItem
{
public:
Node(GraphWidget *graphWidget, int altNum);


int type() const { return Type; }


QRectF boundingRect() const;
QPainterPath shape() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);



protected:

void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

private:


int altN, x, y;
QPointF newPos;
GraphWidget *graph;
};

#endif


node.cpp missing all the different symbols, just drawing one generic x


#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>


#include "node.h"
#include "graphwidget.h"

Node::Node(GraphWidget *graphWidget, int altNum)
: graph(graphWidget)
{
setFlag(ItemIsMovable);
setFlag(ItemSendsGeometryChanges);
setCacheMode(DeviceCoordinateCache);
setZValue(-1);
x = 0; y = 0;
altN = altNum;


}

QRectF Node::boundingRect() const
{

return QRectF(0, 0, 8, 16);
}

QPainterPath Node::shape() const
{
QPainterPath path;
path.addRect(0, 0, 8, 16);
return path;
}

void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
painter->setBrush(Qt::white);
painter->setPen(QPen(Qt::white, 1, Qt::SolidLine));


// generic x

painter->drawLine(0,0,8,16);
painter->drawLine(8,0,0,16);

}
void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
update();
QGraphicsItem::mousePressEvent(event);
}

void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
update();
QGraphicsItem::mouseReleaseEvent(event);
}



that works fine........ as the pic demonstrates.... I want to add the node.h and node.cpp to my MainWindow and implement it like this




void MainWindow::populateScene()
{
int heightH = (hexVec.size() * 16) + 8;

ui->graphicsView_3->setSceneRect(0,0,559, heightH);
dataScene.setSceneRect(0,0,559, heightH);




//call and set up alot of these nodes
// just one for right now

QGraphicsItem itemA = new Node(itemA, 2);
itemA->setPos(50,50);
dataScene.addItem(itemA);


ui->graphicsView_3->setScene(& dataScene);
ui->graphicsView_3->show();
}


dataScene is a public QGrahicsScene of MainWindow

but the node class is somehow not able to namespace the mainwindow? or is passed the correct Scene, View, GraphicItem? I've ripped it up and tried many ways, but can't get one stinking class to work with my mainwindow.....

I have the items drawing great in the desktop widget and most of the scenes are animated, but if I can't get this class to work right, so that I can draw them in a graphicsView, the whole program is for not.....

http://www.baskanos.com/avabiwskomai/mainWindowScreenShot.png

wysota
21st April 2010, 08:08
What is the error you are getting? Also, please don't link to images from 3rd party sites unless necessary, it's against the rules of this site. Use attachments instead.

budda
21st April 2010, 08:56
ooops sorry... just saw the add image icon....
ahh I figured it out...

I was passing an unnecessary QGraphicsItem *parent in the node constructor.
good god that was a frustrating bug!
But now I have 256 ascii chars as custom drawLine GraphicsItems and they draw blindingly fast.....
GraphicsScene.addText and .addSimpleText are no longer needed... I have all those chars
as individual items that have mouseEvents and interactivity....and switching the color is a breeze....
I just need to rip out all the QStrings I am using for converting binary data and it will be very fast indeed.....
QChar is slower than just an int? because it inherits from QString? That is actually ironic.... The first time I made
all these characters in a Turbo C++ 3.2 graphics I was using ints, then switched to chars to because of stack consumption.
now I'm back to the ints..... full circle.....


I will try to edit out the pics.....