2

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!

mathlizee
  • 185
  • 2
  • 12
  • 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 https://doc.qt.io/qt-5/qgroupbox.html ) – Jeremy Friesner Oct 23 '19 at 02:40
  • Or set a QVBoxLayout in the QFrame with a QLabel at the top and a QWidget as a container at the bottom. – eyllanesc Oct 23 '19 at 02:58
  • 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 Oct 23 '19 at 03:22
  • @MaximPaperno The QFrame will be placed into a layout... – mathlizee Oct 23 '19 at 04:39
  • 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 Oct 23 '19 at 05:21

1 Answers1

1

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();
G.M.
  • 12,232
  • 2
  • 15
  • 18