#include <QtGui>
#include <cmath>
namespace {
static inline int gridFloor(const qreal& value)
{
if (value < 0) {
return -1 * static_cast<int>(std::ceil(qAbs(value)));
} else {
return static_cast<int>(std::floor(value));
}
}
static inline int gridCeil(const qreal &value)
{
if (value < 0) {
return -1 * static_cast<int>(std::floor(qAbs(value)));
} else {
return static_cast<int>(std::ceil(value));
}
}
static inline int nextSmallerGrid(const int &value, const int &gridSize)
{
if (value < 0) {
const int absValue = qAbs(value);
return -1 * (absValue + gridSize - (absValue % gridSize));
} else {
return value - (value % gridSize);
}
}
}
{
public:
GridScene(qreal x, qreal y, qreal w, qreal h)
{
}
protected:
{
const int gridSize = 25;
if (backgroundCache.isNull()) {
backgroundCache
= QPixmap(gridSize, gridSize
);
const int middle = gridSize / 2;
{
QPainter backgroundPainter
(&backgroundCache
);
backgroundPainter.setRenderHints(painter->renderHints());
backgroundPainter.
fillRect(QRect(0,
0, gridSize, gridSize
),
QBrush(Qt
::white));
backgroundPainter.
setPen(QPen(Qt
::darkGreen,
0));
backgroundPainter.setBrush(Qt::NoBrush);
backgroundPainter.drawLine(0, middle, gridSize, middle);
backgroundPainter.drawLine(middle, 0, middle, gridSize);
}
}
const int realLeft = gridFloor(rect.left());
const int realRight = gridCeil(rect.right());
const int realTop = gridFloor(rect.top());
const int realBottom = gridCeil(rect.bottom());
const int firstLeftGridLine = nextSmallerGrid(realLeft, gridSize);
const int firstTopGridLine = nextSmallerGrid(realTop, gridSize);
QRectF cacheRect
(0,
0, gridSize, gridSize
);
for (int x = firstLeftGridLine; x < realRight; x += gridSize) {
for (int y = firstTopGridLine; y < realBottom; y += gridSize) {
painter
->drawPixmap
(QRectF(x, y, gridSize, gridSize
),
backgroundCache,
cacheRect);
}
}
}
private:
};
namespace {
static inline QPainterPath constructNodeShape
(const QRectF
& elipseRect
) {
path.addEllipse(elipseRect);
return path;
}
}
{
public:
elipseRect(-4.0, -4.0, 8.0, 8.0),
elipsePath
(constructNodeShape
(QRectF(-3.0,
-3.0,
2.0*3.0,
2.0*3.0))),
elipseShape(constructNodeShape(elipseRect)),
nodePen(Qt::darkRed),
nodeBrush(Qt::NoBrush)
{
setFlags(0);
setAcceptedMouseButtons(0);
}
{
p->setPen(nodePen);
p->setBrush(nodeBrush);
p->setOpacity(1.0);
p->setClipRect(o->exposedRect);
p->drawPath(elipsePath);
}
{
return elipseShape;
}
{
return elipseRect;
}
protected:
};
namespace {
{
resistorPath.
addRect(QRectF(-18.0,
-9.0,
36.0,
18.0));
resistorPath.moveTo(-27, 0);
resistorPath.lineTo(-18, 0);
resistorPath.moveTo(18, 0);
resistorPath.lineTo(27, 0);
return resistorPath;
}
}
{
public:
resistorPath(constructResistorPath()),
boundingBox(resistorPath.boundingRect().adjusted(-1, -1, 1, 1)),
resistorSelectedPen(Qt::darkBlue),
resistorOpenPen(Qt::darkGray,1),
resistorBrush(Qt::NoBrush)
{
setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable);
// comment the following 4 lines to see the performance difference
t->setPos(0,-35);
Node * node = new Node(this,scene);
node = new Node(this,scene);
}
{
if(!(o
->state
& QStyle::State_Open)) p->setPen(resistorOpenPen);
if(o
->state
& QStyle::State_Selected) p->setPen(resistorSelectedPen);
p->setClipRect( o->exposedRect );
p->setBrush(resistorBrush);
p->drawPath(resistorPath);
}
{
return boundingBox;
}
private:
const QPen resistorSelectedPen;
const QPen resistorOpenPen;
};
int main(int argc,char *argv[])
{
GridScene scene(0,0,1024,768);
for(int j = 2; j < 4; ++j)
for(int i = 1; i <11; ++i)
{
Resistor *r = new Resistor(0,&scene);
r->setPos(j*100, i * 50);
}
view->show();
return app.exec();
}
#include <QtGui>
#include <cmath>
namespace {
static inline int gridFloor(const qreal& value)
{
if (value < 0) {
return -1 * static_cast<int>(std::ceil(qAbs(value)));
} else {
return static_cast<int>(std::floor(value));
}
}
static inline int gridCeil(const qreal &value)
{
if (value < 0) {
return -1 * static_cast<int>(std::floor(qAbs(value)));
} else {
return static_cast<int>(std::ceil(value));
}
}
static inline int nextSmallerGrid(const int &value, const int &gridSize)
{
if (value < 0) {
const int absValue = qAbs(value);
return -1 * (absValue + gridSize - (absValue % gridSize));
} else {
return value - (value % gridSize);
}
}
}
class GridScene : public QGraphicsScene
{
public:
GridScene(qreal x, qreal y, qreal w, qreal h)
: QGraphicsScene(x, y, w, h)
{
setItemIndexMethod(QGraphicsScene::NoIndex);
}
protected:
void drawBackground(QPainter *painter, const QRectF &rect)
{
const int gridSize = 25;
if (backgroundCache.isNull()) {
backgroundCache = QPixmap(gridSize, gridSize);
const int middle = gridSize / 2;
{
QPainter backgroundPainter(&backgroundCache);
backgroundPainter.setRenderHints(painter->renderHints());
backgroundPainter.fillRect(QRect(0, 0, gridSize, gridSize), QBrush(Qt::white));
backgroundPainter.setPen(QPen(Qt::darkGreen,0));
backgroundPainter.setBrush(Qt::NoBrush);
backgroundPainter.drawLine(0, middle, gridSize, middle);
backgroundPainter.drawLine(middle, 0, middle, gridSize);
}
}
const int realLeft = gridFloor(rect.left());
const int realRight = gridCeil(rect.right());
const int realTop = gridFloor(rect.top());
const int realBottom = gridCeil(rect.bottom());
const int firstLeftGridLine = nextSmallerGrid(realLeft, gridSize);
const int firstTopGridLine = nextSmallerGrid(realTop, gridSize);
QRectF cacheRect(0, 0, gridSize, gridSize);
for (int x = firstLeftGridLine; x < realRight; x += gridSize) {
for (int y = firstTopGridLine; y < realBottom; y += gridSize) {
painter->drawPixmap(QRectF(x, y, gridSize, gridSize),
backgroundCache,
cacheRect);
}
}
}
private:
QPixmap backgroundCache;
};
namespace {
static inline QPainterPath constructNodeShape(const QRectF& elipseRect)
{
QPainterPath path;
path.addEllipse(elipseRect);
return path;
}
}
class Node : public QGraphicsItem
{
public:
Node(QGraphicsItem *par = 0, QGraphicsScene *sc = 0)
: QGraphicsItem(par,sc),
elipseRect(-4.0, -4.0, 8.0, 8.0),
elipsePath(constructNodeShape(QRectF(-3.0, -3.0, 2.0*3.0, 2.0*3.0))),
elipseShape(constructNodeShape(elipseRect)),
nodePen(Qt::darkRed),
nodeBrush(Qt::NoBrush)
{
setFlags(0);
setAcceptedMouseButtons(0);
}
void paint(QPainter* p,const QStyleOptionGraphicsItem *o, QWidget *)
{
p->setPen(nodePen);
p->setBrush(nodeBrush);
p->setOpacity(1.0);
p->setClipRect(o->exposedRect);
p->drawPath(elipsePath);
}
QPainterPath shape() const
{
return elipseShape;
}
QRectF boundingRect() const
{
return elipseRect;
}
protected:
const QRectF elipseRect;
const QPainterPath elipsePath;
const QPainterPath elipseShape;
const QPen nodePen;
const QBrush nodeBrush;
};
namespace {
static inline QPainterPath constructResistorPath()
{
QPainterPath resistorPath;
resistorPath.addRect(QRectF(-18.0, -9.0, 36.0, 18.0));
resistorPath.moveTo(-27, 0);
resistorPath.lineTo(-18, 0);
resistorPath.moveTo(18, 0);
resistorPath.lineTo(27, 0);
return resistorPath;
}
}
class Resistor : public QGraphicsItem
{
public:
Resistor(QGraphicsItem *par = 0, QGraphicsScene *scene = 0)
: QGraphicsItem(par,scene),
resistorPath(constructResistorPath()),
boundingBox(resistorPath.boundingRect().adjusted(-1, -1, 1, 1)),
resistorSelectedPen(Qt::darkBlue),
resistorOpenPen(Qt::darkGray,1),
resistorBrush(Qt::NoBrush)
{
setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable);
// comment the following 4 lines to see the performance difference
QGraphicsTextItem *t = new QGraphicsTextItem("R1 = 100k",this,scene);
t->setPos(0,-35);
Node * node = new Node(this,scene);
node->setPos(QPointF(-30,0));
node = new Node(this,scene);
node->setPos(QPointF(30,0));
}
void paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *)
{
if(!(o->state & QStyle::State_Open))
p->setPen(resistorOpenPen);
if(o->state & QStyle::State_Selected)
p->setPen(resistorSelectedPen);
p->setClipRect( o->exposedRect );
p->setBrush(resistorBrush);
p->drawPath(resistorPath);
}
QRectF boundingRect() const
{
return boundingBox;
}
private:
const QPainterPath resistorPath;
const QRectF boundingBox;
const QPen resistorSelectedPen;
const QPen resistorOpenPen;
const QBrush resistorBrush;
};
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
GridScene scene(0,0,1024,768);
for(int j = 2; j < 4; ++j)
for(int i = 1; i <11; ++i)
{
Resistor *r = new Resistor(0,&scene);
r->setPos(j*100, i * 50);
}
QGraphicsView *view = new QGraphicsView(&scene);
view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
view->setDragMode(QGraphicsView::RubberBandDrag);
view->show();
return app.exec();
}
To copy to clipboard, switch view to plain text mode
Bookmarks