0

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

JokerMartini
  • 5,674
  • 9
  • 83
  • 193
  • Are you asking how to create a new project in Qt creator? The first question is totally unclear. – Jaa-c Sep 11 '18 at 13:31
  • I am almost ready with the example code. Give me a moment to finish and test it. – scopchanov Sep 11 '18 at 13:33
  • @Jaa-c I'm asking how I create a subfolder in my current project, where the subfolder contains the pri file and the headers and source folder. – JokerMartini Sep 11 '18 at 13:56
  • 1
    @JokerMartini I thought your question was "Creating subclass of QLabel in Qt Creator" – Moia Sep 11 '18 at 14:08
  • Your question is unrelated to the code you've provided, which is causing confusion. Please clarify what you're asking (probably by removing anything unrelated). Specifically, you have some info, a code example, and then a question that is unrelated. – jonspaceharper Sep 11 '18 at 14:27
  • Also, this should be helpful: https://stackoverflow.com/questions/1176666/how-to-create-a-subdirectory-for-a-project-qtcreator – jonspaceharper Sep 11 '18 at 14:29

1 Answers1

3

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

Community
  • 1
  • 1
scopchanov
  • 7,966
  • 10
  • 40
  • 68
  • 1
    What do you recommend i do when you say to select a subfolder. Do you mean a folder within the root of my project which is called CustomControls? You managed to answer all my questions with accurate response and details i really appreciate your help. I think this will help out a lot in terms of what i was trying to do. thank you so much. – JokerMartini Sep 11 '18 at 14:38
  • 1
    @JokerMartini, you are very welcome. As for the subfolder, I mean that when a new class is created, a path could be setup and you could select where your class will reside with respect to the rest of your project. But as the exact folder structure is influenced by personal preferences, as well as project requirements and specifics, I can't make a good suggestion here. – scopchanov Sep 11 '18 at 14:42
  • Secondly when adding the protected:void paintEvent(QPaintEvent *event); how did you know to add the following word of (override) to the protected method? It did not automatically appear. – JokerMartini Sep 11 '18 at 14:44
  • 1
    @JokerMartini, there is a checkbox on the dialog window: _Add override equivalent..._ – scopchanov Sep 11 '18 at 14:46
  • Thank you so much. If i had additional questions about a few things, did you have a recommended form on communication rather than making this a lengthy chat? – JokerMartini Sep 11 '18 at 15:18
  • @JokerMartini, I think the standard way works pretty well. Just post a new question and try to describe the problem as precise as possible. There are excellent experts around here, so certainly someone would be able to help. I would do that as well, if I am able to. – scopchanov Sep 11 '18 at 15:26
  • I noticed in your code I can not create a new LabelHeader("Title") the same way i create a new QLabel("Title"). Why is that if my control is a subclass of QLabel? – JokerMartini Sep 11 '18 at 15:29
  • @JokerMartini, check the code at the GitHub repository now. – scopchanov Sep 11 '18 at 15:35