JokerMartini
JokerMartini

Reputation: 6147

Creating subclass of QLabel in Qt Creator using C++

I'm recently new to the c++ world. My background is mainly in python and some application specific scripting languages. Anywho, I wanted to get some general feedback and converting my subclass of QLabel written in pyside and convert it to work with a C++ application in Qt Creator. I'm not looking for someone to do the entire project for me. I just need some guidance on how to add/setup a custom control in my Qt project.

You'll notice in my subclass I've simply just overwritten the paint event of the label in order to create the dotted pattern to fill the empty space to the right of the label as seen here:

enter image description here

Code for my custom label in Pyside:

class QLabelHeader(QtWidgets.QLabel):

    def __init__(self, parent=None, **kwargs):
        super(QLabelHeader, self).__init__(parent)   

    # events
    def paintEvent(self, event):
        # calculate font width
        metrics = QtGui.QFontMetrics(self.font())
        text_width = metrics.boundingRect(self.text()).width()

        # calculate dimensions
        y = int(self.height() * 0.5 - 2)
        x = text_width + 4
        width = self.width() - x

        # create pattern
        px = QtGui.QPixmap(4,4)
        px.fill(QtCore.Qt.transparent)
        pattern_painter = QtGui.QPainter(px)
        pattern_painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))
        pattern_painter.setBrush(QtGui.QBrush(QtGui.QColor(200,200,200), QtCore.Qt.SolidPattern))
        pattern_painter.drawRect(0,0,1,1)
        pattern_painter.drawRect(2,2,1,1)
        pattern_painter.end()

        # draw tiled pixmap
        painter = QtGui.QPainter(self)
        painter.drawTiledPixmap(x,y,width,5,px) 
        painter.end()

        super(QLabelHeader, self).paintEvent(event)

Question:

  1. I've seen other sample projects online that include custom controls with a folder structure like seen here, which is a subfolder within a larger project. How do they create this folder structure and it's set of files?

  2. As an added bonus if anyone feels like showing me a preview/psuedo code of what my h and cpp file would look like for overriding the QLabel's paint event like my pyside code.

enter image description here

Upvotes: 0

Views: 1434

Answers (1)

scopchanov
scopchanov

Reputation: 8399

Solution

  1. Add a new class to your project in Qt creator going to File->New File or Project->C++->C++ Class. Make the class inherit from QWidget from the drop-down menu. Select a subfolder and give the class a name

Note: As a piece of advise, do not name your classes with Q prefix, as it might lead to a confusion.

  1. In the header substitute the base class and the include with QLabel
  2. Right click the name of the base class and select Refactor->Insert Virtual Functions of Base Classes and add paintEvent
  3. Right click paintEvent and select Refactor->Add Definition in xxx.cpp
  4. Go to the definition and put your code there

The translation should be pretty much straightforward, once you know the syntax of both languages.

Example

To help you with the process, I have prepared an example of how your code could be translated into C++:

LabelHeader.h:

#ifndef LABELHEADER_H
#define LABELHEADER_H

#include <QLabel>

class LabelHeader : public QLabel
{
    Q_OBJECT
public:
    explicit LabelHeader(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event) override;
};

#endif // LABELHEADER_H

LabelHeader.cpp:

#include "LabelHeader.h"
#include <QPainter>

LabelHeader::LabelHeader(QWidget *parent) :
    QLabel(parent)
{

}

void LabelHeader::paintEvent(QPaintEvent *event)
{
    // calculate font width
    QFontMetrics metrics(font());
    int text_width = metrics.boundingRect(text()).width();

    // calculate dimensions
    int y = height() * 0.5 - 2;
    int x = text_width + 4;
    int w = width() - x;

    // create pattern
    QPixmap px(4, 4);
    px.fill(Qt::transparent);

    QPainter pattern_painter(&px);

    pattern_painter.setPen(Qt::NoPen);
    pattern_painter.setBrush(QBrush(QColor(200, 200, 200), Qt::SolidPattern));
    pattern_painter.drawRect(0, 0, 1, 1);
    pattern_painter.drawRect(2, 2, 1, 1);
//  pattern_painter.end();

    // draw tiled pixmap
    QPainter painter(this);

    painter.drawTiledPixmap(x, y, w, 5, px);
//  painter.end();

    QLabel::paintEvent(event);
}

Note: I also took the liberty to revise the code after it has been translated and omit or commented parts, which are not necessary.

The full code of the example is available on GitHub.

Result

When used in the provided example application, this class produces a similar result:

enter image description here

Upvotes: 3

Related Questions