1
votes

I need to implement a QFrame that has a title (see image). However, after reading QFrame's documentation and trying to re-implement the paintEvent(QPaintEvent*) method, I failed to find any solution.

I was wondering if any of you could provide a small exemple demonstrating how I can achieve somthing like this:

enter image description here

Thank you!

1
The QGroupBox class might be suitable for your purpose -- it takes a title string as its first constructor object, and displays it at the top-left of its area (see screenshots at doc.qt.io/qt-5/qgroupbox.html ) - Jeremy Friesner
Or set a QVBoxLayout in the QFrame with a QLabel at the top and a QWidget as a container at the bottom. - eyllanesc
Is this for a dialog-like top-level window, or will the QFrame be placed into a layout? Any top-level QWidget can have a title bar added by just setting the right QWdiget::windowFlags(). Though I've never tried that with an embedded widget (but it should work). - Maxim Paperno
@MaximPaperno The QFrame will be placed into a layout... - mathlizee
Then you're probably best off "faking it" with a layout and label like eyllanesc suggests (do you need example of that?). (I guess an embedded QWidget can't have a title bar... I must be thinking of QGraphicsWidgets.) You could do it with custom painting also, if you really want to go that route specifically, but it would be more involved. You should be able to set the rounding with CSS... but the background of whatever it's over will show through on the corners. - Maxim Paperno

1 Answers

1
votes

As an alternative to creating your own compound widget you might be able to use the contents margins to fake a title bar...

#include <QFont>
#include <QFrame>
#include <QPainter>

class titled_frame: public QFrame {
    using super = QFrame;
public:
    explicit titled_frame (const QString &title = "A Title Here", QWidget *parent = nullptr)
        : super(parent)
        , m_title(title)
        {
            /*
             * Set the top margin based on the font height.
             */
            setContentsMargins(0, 2 * fontInfo().pixelSize(), 0, 0);
        }
protected:
    virtual void paintEvent (QPaintEvent *event) override
        {

            /*
             * Draw the title centred in the top margin.
             */
            QPainter painter(this);
            QRect title_rect(QPoint(0, 0), QSize(width(), contentsMargins().top()));
            painter.fillRect(title_rect, Qt::blue);
            painter.setPen(Qt::black);
            painter.drawText(title_rect, Qt::AlignCenter, m_title);

            /*
             * Defer to the base class implementation to update everything else.
             */
            super::paintEvent(event);
        }
private:
    QString m_title;
};

Then use as...

titled_frame tf("A Title Here");
auto *layout = new QVBoxLayout(&tf);
layout->addWidget(new QLabel("Any QLayout or QWidget here..."));
tf.show();