Search code examples
c++qtqwidgetpainteventqframe

QFrame With Title


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!


Solution

  • 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();