QFrame с заголовком

Мне нужно реализовать QFrame с заголовком (см. изображение). Однако, прочитав документацию QFrame и попытавшись повторно реализовать метод paintEvent(QPaintEvent*), я не нашел никакого решения.

Мне было интересно, может ли кто-нибудь из вас привести небольшой пример, демонстрирующий, как я могу добиться чего-то вроде этого:

введите здесь описание изображения

Благодарю вас!


person mathlizee    schedule 23.10.2019    source источник
comment
Для ваших целей может подойти класс QGroupBox — он принимает строку заголовка в качестве своего первого объекта-конструктора и отображает ее в левом верхнем углу своей области (см. io/qt-5/qgroupbox.html" rel="nofollow noreferrer">doc.qt.io/qt-5/qgroupbox.html )   -  person Jeremy Friesner    schedule 23.10.2019
comment
Или установите QVBoxLayout в QFrame с QLabel вверху и QWidget в качестве контейнера внизу.   -  person eyllanesc    schedule 23.10.2019
comment
Это для диалогового окна верхнего уровня или QFrame будет помещен в макет? К любому QWidget верхнего уровня можно добавить строку заголовка, просто установив правильный QWdiget::windowFlags(). Хотя я никогда не пробовал это со встроенным виджетом (но это должно работать).   -  person Maxim Paperno    schedule 23.10.2019
comment
@MaximPaperno QFrame будет помещен в макет...   -  person mathlizee    schedule 23.10.2019
comment
Тогда вам, вероятно, лучше всего сымитировать его с макетом и меткой, как предлагает eyllanesc (вам нужен пример этого?). (Я предполагаю, что встроенный QWidget не может иметь строку заголовка... Я, должно быть, думаю о QGraphicsWidgets.) Вы также можете сделать это с помощью пользовательского рисования, если вы действительно хотите пойти по этому пути конкретно, но это было бы более сложно. Вы должны иметь возможность установить закругление с помощью CSS ... но фон того, что закончилось, будет просвечиваться по углам.   -  person Maxim Paperno    schedule 23.10.2019


Ответы (1)


В качестве альтернативы созданию собственного составного виджета вы можете использовать поля содержимого для имитации строки заголовка...

#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;
};

Тогда используйте как...

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