Sample project started as a QT Gui Application and contains main.cpp, CustomQGraphicsScene.h, CustomQGraphicsScene.cpp, Dialog.h and Dialog.cpp files.
Project Directory Structure in Qt Creator IDE :
DrawGridOnQGraphicsScene.pro is the project configuration file and contains:
QT += core gui TARGET = DrawGridOnQGraphicsScene TEMPLATE = app SOURCES += main.cpp \ Dialog.cpp \ CustomQGraphicsScene.cpp HEADERS += Dialog.h \ CustomQGraphicsScene.h
main.cpp file contains the custom QDialog instance and shows it.
#include <QApplication> #include "Dialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); }
Dialog.h is derived from QDialog class which contains QGraphicsView in it.
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> class CustomQGraphicsScene; class QGraphicsView; class QVBoxLayout; class Dialog : public QDialog { Q_OBJECT public: Dialog(QWidget *parent = 0); ~Dialog(); private: CustomQGraphicsScene* scene; QGraphicsView* view; QVBoxLayout* layout; }; #endif // DIALOG_H
Dialog.cpp contains implementation details for derived QDialog class.
#include "Dialog.h" #include "CustomQGraphicsScene.h" #include <QVBoxLayout> #include <QGraphicsView> Dialog::Dialog(QWidget *parent) : QDialog(parent) { scene = new CustomQGraphicsScene(this); view = new QGraphicsView(scene,this); layout = new QVBoxLayout(this); layout->addWidget(view); setLayout(layout); resize(270,200); } Dialog::~Dialog() { delete scene; delete view; }
Custom QDialog creates an instance of derived QGraphicsScene and displays in a QGraphicsView.
CustomQGraphicsScene.h is derived from QGraphicsScene in which drawBackground() function is reimplemented to draw grid on it.
#ifndef CUSTOMQGRAPHICSSCENE_H #define CUSTOMQGRAPHICSSCENE_H #include <QGraphicsScene> class CustomQGraphicsScene : public QGraphicsScene { public: CustomQGraphicsScene(QObject *parent); protected: void drawBackground(QPainter * painter, const QRectF & rect ); }; #endif // CUSTOMQGRAPHICSSCENE_H
CustomQGraphicsScene.cpp contains implementation details for derived QGraphicsScene class.
#include "CustomQGraphicsScene.h" #include <QPainter> static const int GRID_STEP = 30; inline qreal round(qreal val, int step) { int tmp = int(val) + step /2; tmp -= tmp % step; return qreal(tmp); } CustomQGraphicsScene::CustomQGraphicsScene(QObject *parent ) : QGraphicsScene(parent) {} void CustomQGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) { int step = GRID_STEP; painter->setPen(QPen(QColor(200, 200, 255, 125))); // draw horizontal grid qreal start = round(rect.top(), step); if (start > rect.top()) { start -= step; } for (qreal y = start - step; y < rect.bottom(); ) { y += step; painter->drawLine(rect.left(), y, rect.right(), y); } // now draw vertical grid start = round(rect.left(), step); if (start > rect.left()) { start -= step; } for (qreal x = start - step; x < rect.right(); ) { x += step; painter->drawLine(x, rect.top(), x, rect.bottom()); } }
Drawing grid process is divided into two substeps such as drawing vertical and drawing horizontal lines. Derived QGraphicsScene instance in which drawBackground() function is reimplemented looks like following screenShot :
Hello, I know this thread is so old, but I think I can contribute. Recently I had to do something similar and I got the same problem, eficiency, I develop a simple solution with a simple technique that uses a bitmap to draw all, is so fast and efficient, the explanation is in my website Creación de grilla de forma eficiente en QGraphicsView/QGraphicsScene but is spanish, if you think that you can exploit this, then visit it.
ReplyDeleteJust a side-note: I would advise against calling `delete` on your scene and view. Both have an assigned parent (which you did when you called their constructors and passed `this` (that is the `Dialog`'s instance) as a parent). It's not that `delete` is something you shouldn't use at all but in your case it's a waste and basically eliminates the automatic memory management Qt offers with the whole parent-child stuff.
ReplyDelete