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