Qt中的QFrame之类的自定义小部件

时间:2019-06-26 16:55:43

标签: c++ qt widget qframe

我已经在Qt creatorC++)中编写了自己的课程。我想要实现类似于下面给出的图片(请参见border左上角的标签“ Options”)(即使存在知名的类,您也可以提及这些类的名称,但是我仍然想试试我的自定义课程,以了解有关Qt的更多信息:

enter image description here

我通过编写自己的课程实现了相同的目的:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QFrame>
#include <QLabel>

class Widget: public QFrame {
Q_OBJECT

public:
    void resizeEvent(QResizeEvent *event) override;
    void paintEvent(QPaintEvent *event) override;

public:
    Widget(QWidget *parent = nullptr);
    ~Widget(void) override;

private:
    QLabel *label_ = nullptr;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"

#include <QDebug>
#include <QHBoxLayout>
#include <QResizeEvent>

#include <QPainter>
#include <QPaintEvent>

#include <QString>

Widget::Widget(QWidget *parent): QFrame(parent)
{
    qDebug() << "Creating Widget";

    label_ = new QLabel;
    label_->setText(tr("Size: 0"));

    QHBoxLayout *hlayout = new QHBoxLayout;
    hlayout->addStretch(1);
    hlayout->addWidget(label_);
    hlayout->addStretch(1);

    QHBoxLayout *vlayout = new QHBoxLayout;
    vlayout->addStretch(1);
    vlayout->addLayout(hlayout);
    vlayout->addStretch(1);

    setLayout(vlayout);
    setFrameStyle(2);
}

Widget::~Widget(void)
{

}

void Widget::resizeEvent(QResizeEvent *event)
{
    QString text = QString("Size: %1 . %2").arg(event->size().width()).arg(event->size().height());
    qDebug() << "Resize Event: Old: " << event->oldSize() << " New: " << event->size() << " Text: " << text;
    label_->setText(text);
}

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    qDebug() << "Paint Evemt";

    QPainter painter(this);
    painter.setPen(QColor("Red"));
//    painter.setBrush(QColor("Red"));
    int width = size().width();
    int height = size().height();

    double factor = 1.0 / 10.0;
    QLine third = QLine(int(width * (1 - factor)), int(height * factor), int(width * (1 - factor)), int(height * (1 - factor)));

    QString text("Hello Sir");
    QRect textRect = QFontMetrics(painter.font()).boundingRect(text);

    qDebug() << textRect;

    painter.drawLine(int(width * factor) + textRect.width(), int(height * factor), int(width * (1 - factor)), int(height * factor));
    painter.drawLine(int(width * factor), int(height * factor), int(width * (factor)), int(height * (1 - factor)));
    painter.drawLine(third);
    painter.drawLine(int(width * factor), int(height * (1 - factor)), int(width * (1 - factor)), int(height * (1 - factor)));

    painter.drawText(QPoint(int(width * factor), int(height * factor + textRect.height() / 2)), text);
}

我的窗口小部件如下所示(请忽略居中的QLabel,它用于调试和学习):

enter image description here

我将定义setHeader(QString)之类的函数,以将text设置在边框的左上角。

现在,我必须扩展我的课程以包含以下条款:

  1. 我不希望任何东西在边框上或边框上方绘制。我的此类将在以后用于在其中添加许多小部件(将被子类化)。如何实现呢?如何停止或限制自定义窗口小部件中将包含的窗口小部件的绘画或绘图?

  2. 我想验证到目前为止已实现的实现。我是否使用Qt的标准方法?我可以进一步改善吗?

1 个答案:

答案 0 :(得分:0)

您不必担心窗口小部件边框外的窗口小部件绘制。窗口小部件绘画会自动被其父对象裁剪,因此Qt会为您处理。

我相信您想要的是在垂直布局中添加一个空的QWidget。该小部件将用作子类要添加的任何内容的容器小部件。您可以将该小部件暴露给调用者,以便他们可以在其上放置自己的布局(这些布局将在所需的任何布局中包含任何子小部件),也可以添加新方法(例如“ setContainerLayout”),调用者可以构建布局并将其应用于容器小部件。

将容器小部件放置到内部布局中时,您可能需要尝试使用布局边距来将容器保持在边界内。