【问题标题】:Can't use QPainter in paintEvent of custom QWidget (Qt5)无法在自定义 QWidget(Qt5)的paintEvent 中使用 QPainter
【发布时间】:2016-09-23 23:48:44
【问题描述】:

有问题的错误如下:

QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::setFont: Painter not active

在查看了大量在线论坛帖子后,这些帖子都归结为人们犯了同样的错误,试图在paintEvent() 之外的小部件上绘画,我一直没有运气。我尝试直接在这个自定义 QWidget 子类上绘图,我尝试制作一个子 QWidget 并在其上绘图。谁能告诉我我做错了什么(可能对其他人来说很明显)?

提前致谢。

标题:

#ifndef TEXTDISPLAY_H
#define TEXTDISPLAY_H

#include <QWidget>

class TextDisplay : public QWidget
{
    Q_OBJECT

public:
    TextDisplay(QString text, QString fontFamily = "Helvetica", int fontSize = 20,
                int fontColor = Qt::black, QWidget* parent = 0);

protected:
    void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE;
    void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;

private:
    QString text;
    QString fontFamily;
    int fontSize;
    int fontColor;
};

#endif // TEXTDISPLAY_H

Cpp:

#include "textdisplay.h"
#include <QPainter>


TextDisplay::TextDisplay(QString text, QString fontFamily, int fontSize,
                         int fontColor, QWidget* parent)
    : QWidget(parent), text(text), fontFamily(fontFamily),
      fontSize(fontSize), fontColor(fontColor)
{
    this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
}

void TextDisplay::resizeEvent(QResizeEvent*) {
    paintEvent(NULL);
}

void TextDisplay::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.setPen(fontColor);
    painter.setFont(QFont(fontFamily, fontSize));

    QRect rect(QPoint(0, 0), this->size());
    QRect bound;
    QTextOption options;
    options.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);

    painter.drawText(rect, Qt::TextWordWrap | Qt::TextWrapAnywhere, text, &bound);

    this->setMinimumHeight(bound.size().height());
}

使用解决方案编辑:

感谢两位响应者 - 我需要做两件事才能让它发挥作用:

a) 摆脱paintEvent(NULL)。我也摆脱了 resizeEvent 覆盖,建议没有必要。

b) 设置小部件的最小尺寸。没有这个,paintEvent 就不会被 Qt 调用。

【问题讨论】:

  • 您的代码看起来不错,但问题是您直接从TextDisplay::resizeEvent() 调用TextDisplay::paintEvent()。这就是您收到警告的原因。
  • 消除了警告,谢谢。

标签: c++ qt qt5


【解决方案1】:

如果您想为您的小部件安排重绘,只需致电update()

如果您需要立即重绘(您几乎不需要),您可以致电 repaint()

直接调用paintEvent()是不行的——Qt需要准备backing store来处理绘画,所以不能绕过更新机制。相反,调用上面的方法,这将导致对paintEvent() 的调用(如果小部件是可见的、未被遮挡的等等)。

还请注意,您不需要重新实现resizeEvent() 只是为了更新您的小部件。 Qt 应该已经为您完成了...

【讨论】:

  • 另请注意,如果可能,update() 请求会被合并(而 repaint() 则不会)。这可以大大加快速度。
猜你喜欢
  • 2018-02-04
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
相关资源
最近更新 更多