Background Grid in Qt Widgets Applications
If you are developing a drawing application, a CAD program or any type of software, which allows the user to arrange items in a document, it is a good idea to provide some kind of a visual aid to support the proper placement of those items. Displaying a grid as a background might be just the right solution in this case. It could also enhance the visual appeal of your application, making it look more professional.
In this tutorial we are going to see how to display a grid as a background of a graphical scene in a Qt Widgets application.
Basic Application
Suppose that our application consists of a MainWindow
subclassed from QWidget
, which displays a QGraphicsScene
with one movable QGraphicsRectItem
like this:
#include "MainWindow.h" #include <QBoxLayout> #include <QGraphicsView> #include <QGraphicsRectItem> MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { auto *l = new QVBoxLayout(this); auto *graphicsView = new QGraphicsView(this); auto *item = new QGraphicsRectItem(0, 0, 100, 60); item->setPos(70, 90); item->setBrush(Qt::red); item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); graphicsView->setScene(new QGraphicsScene(this)); graphicsView->setSceneRect(0, 0, 800, 800); graphicsView->setAlignment(Qt::AlignLeft | Qt::AlignTop); graphicsView->scene()->addItem(item); // TODO Add grid l->addWidget(graphicsView); resize(400, 400); }
As a result, the following window is produced:

Displaying a Static Grid
Now let’s say, that for a whatever reason, we need to display a background grid.
One approach would be to compose the grid by ourselves, adding the corresponding items (lines or rectangles) to the QGraphicsScene
manually, e.g. using for
loops. However, this is not a good idea, because:
- the application’s performance might degrade for huge scenes with many items,
- it would be harder to work with the scene, because all grid components would become its children, like any other item, added to it,
- manual positioning is tedious and prone to errors.
Another approach is to take advantage of the fact, that a grid is actually a repetitive pattern. This way we could prepare a small image in advance and instead of adding it to the scene, setting it as a background of the QGraphicsView
in a tiled manner.
Below are some example patterns, which might be used as a grid. Please note, that the figures represent a zoomed version of each image. The actual images, used for this tutorial, are 20px in width and height. The top left corner serves as a reference point (0, 0)
. The images are added to the application’s resources under pix/images
.



QGraphicsView
supports custom backgrounds through its backgroundBrush
property. Hence, adding a background grid to the graphics view is nothing more than specifying one of the prepared images as its background brush:
graphicsView->setBackgroundBrush(QPixmap(":/pix/images/grid_square.png"));
This produces a nice background grid in a very efficient way:

Indeed we have implemented a background grid. However, it is not yet possible to make any adjustments to its appearance.
Of course, we could call QGraphicsView::setBackgroundBrush
with a different argument:
graphicsView->setBackgroundBrush(QPixmap(":/pix/images/grid_cross.png"));
which would produce a different type of a grid:

Hence, to allow us to have more flexibility with regard to the change of the grid’s appearance, we could make the image path in the call to QGraphicsView::setBackgroundBrush
variable:
graphicsView->setBackgroundBrush(QPixmap(":/pix/images/" + pattern + ".png"));
Now the image, used to create the grid, could be specified at runtime.
If this is all what you need for your application, this tutorial might end here. However, if you are looking for an even more flexible solution, please do read further.
Making the Grid Dynamic
Currently we are able to give the background grid an arbitrary look, as long as we have the necessary images prepared in advance. An obvious drawback of this approach is the rapid increase of the number of images we have to prepare, when adding more cutomization parameters, e.g. a grid step and a color. To overcome this drawback, instead of having a potentially huge number of prepared images, we could let an image to be drawn with the desired settings on-demand.
To demonstrate this approach, we will create a new class, PixmapBuilder
, to which we are going to delegate the drawing of the images. This class will have only one public method declared in the following way:
static QPixmap drawPattern(int type, int step, const QColor &color);
The method accepts the grid’s type, step and color as arguments and returns a QPixmap
, which we can directly use in the call to QGraphicsView::setBackgroundBrush
. PixmapBuilder
is not storing any state, hence we can make drawPattern
static.
Furthermore, we declare three private static methods, one for each of the supported patterns, to perform the actual drawing:
static void drawSquare(QPainter *painter, int width, const QColor &color); static void drawCross(QPainter *painter, int width, const QColor &color); static void drawFancy(QPainter *painter, int width, const QColor &color);
To simplify the selection of a particular pattern, we define the pattern types as an enumeration:
enum PixmapType : int { PT_Square = 0, PT_Cross, PT_Fancy };
Now, let us start with the implementation of the class methods we have declared.
The pattern will be drawn on the QPixmap
by a QPainter
. Thus, in PixmapBuilder::drawPattern
we need to:
- create a
QPixmap
with the desired size and fill it with a transparent color, - create a
QPainter
and use aswitch-case
statement to call the corresponding draw method with the painter as an argument,
which in code looks like this:
QPixmap PixmapBuilder::drawPattern(int type, int step, const QColor &color) { QPixmap pixmap(step, step); QPainter painter; int pixmapWidth = pixmap.width() - 1; pixmap.fill(Qt::transparent); painter.begin(&pixmap); switch (type) { case PT_Square: drawSquare(&painter, pixmapWidth, color); break; case PT_Cross: drawCross(&painter, pixmapWidth, color); break; case PT_Fancy: drawFancy(&painter, pixmapWidth, color); break; } return pixmap; }
As for the actual drawing, the code for the pattern of a squared grid looks like this:
void PixmapBuilder::drawSquare(QPainter *painter, int width, const QColor &color) { painter->setPen(color); painter->drawLine(0, 0, width, 0); painter->drawLine(0, 0, 0, width); }
The following snippet draws the pattern of a crossed grid:
void PixmapBuilder::drawCross(QPainter *painter, int width, const QColor &color) { painter->setPen(color); painter->drawLine(0, 0, 2, 0); painter->drawLine(0, 0, 0, 2); painter->drawLine(0, width - 1, 0, width); painter->drawLine(width - 1, 0, width, 0); }
And finally, the fancy pattern is drawn in the following way:
void PixmapBuilder::drawFancy(QPainter *painter, int width, const QColor &color) { int halfWidth = 0.5*width + 0.5; painter->setPen(color.lighter(106)); painter->drawLine(0, halfWidth, width, halfWidth); painter->drawLine(halfWidth, 0, halfWidth, width); painter->setPen(color); painter->drawLine(0, 0, width, 0); painter->drawLine(0, 0, 0, width); painter->setPen(color.darker(118)); painter->drawPoint(halfWidth, halfWidth); painter->setPen(color.darker(160)); painter->drawPoint(0, 0); }
Now we are able to use the PixmapBuilder
in the MainWindow
to produce the desired image. At this point changing the grid is as easy as calling PixmapBuilder::drawPattern
, specifying the desired pattern type, step and color values.
For example the following code produces a square magenta grid with a step of 100px:
graphicsView->setBackgroundBrush(PixmapBuilder::drawPattern(PixmapBuilder::PT_Square, 100, "#C000C0"));

And here is how to produce a green grid with cross marks and a step of 40px:
graphicsView->setBackgroundBrush(PixmapBuilder::drawPattern(PixmapBuilder::PT_Cross, 40, "#009000"));

This way it is possible to setup the background grid at runtime.
Practical hint: In a real-world application the grid settings could be made available to the user in a dedicated input form with three controls – for the pattern type, the step and the color of the grid. The selected values could be stored as QSettings
and retrieved later to be used in the calls to PixmapBuilder::drawPattern
.
Exercises
The full code of this tutorial is available on Github. I highly encourage you to download, examine and play with it. To solidify the knowlege you have just obtained, do the following exercises:
Exersice 1: Add a support for a dotted pattern to the application by making the following changes to PixmapBuilder
:
- add a new value to the
PixmapType
enumeration, - declare a new private static method to draw the dotted pattern and implement it,
- add a new
case
to theswitch
statement inPixmapBuilder::drawPattern
to call the newly created draw method.
Exercise 2: Allow the fill color of the grid to be specified by making the following changes to PixmapBuilder
:
- add a new argument,
fillColor
, of typeconst QColor &
to the signature ofPixmapBuilder::drawPattern
, - in
drawPattern
usefillColor
to fill thepixmap
, instead ofQt::transparent
.
Exercise 3: Allow the grid to be toggled on and off by the user by making the following changes to MainWindow
:
- add a private attribute,
m_grid
, of typeQPixmap
toMainWindow
and initialize it with the returned value of a call toPixmapBuilder::drawPattern
, - add a checkable
QPushButton
to the layout ofMainWindow
, - connect the push button to a lambda function, where the background brush of
graphicsView
is set to eitherQBrush()
, off-state, orQBrush(m_pixmap)
, on-state, depending on the checked state of the push button.
Conclusion
In this tutorial you have learned how to draw images at runtime with Qt and use them as a background grid of QGraphicsView
. Additional benefit for you is the possibility to use this approach for drawing images on-demand for any other visual element of your application’s user interface, as the icons of the push buttons for example, thus making it easily customizable.
In the next tutorial we are going to see how to obtain the same results with QML.