paintEvent 未在自定义小部件中调用

问题描述 投票:0回答:1

我试图在每次单击鼠标时在鼠标位置绘制一个矩形。

目前设置如下:

TableMaker
是我的主窗口,大部分是在 Qt Designer 中生成的。

我对

QWidget
RenderArea
进行了子类化,并将其添加到我的
ui
的框架内。

我目前有

TableMaker::mousePressEvent
renderArea
中调用一个函数,该函数创建一个新的
QRect
并在向量中保留对其的引用。

到目前为止,一切正常,当我签入调试器时,它确实创建了这些

QRect
并将它们存储在每次按下鼠标时。

但是,我尝试重写

paintEvent
renderArea
,以便它将更新并绘制这些新的
QRect
,但它永远不会被调用。

我觉得我误解了绘画和相关事件的工作方式,以及谁应该真正拥有被覆盖的所有权

paintEvent

下面是 2 个类

TableMaker
RenderArea
的代码:

main.cpp:

#include "TableMaker.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TableMaker w;
    w.show();
    return a.exec();
}

TableMaker.cpp:

#include "TableMaker.h"

TableMaker::TableMaker(QWidget *parent) : QMainWindow(parent)
{
    ui.setupUi(this);
    renderArea = new RenderArea;
    QGridLayout* drawAreaLayout = new QGridLayout;
    drawAreaLayout->addWidget(renderArea);
    ui.tentFrame->setLayout(drawAreaLayout);
}

void TableMaker::mousePressEvent(QMouseEvent* e) {
    renderArea->addNewTable(e->pos());
    renderArea->update();
}

TableMaker::~TableMaker()
{}

TableMaker.h:

#include <QtWidgets/QMainWindow>
#include <QtWidgets>
#include <QtGui>
#include "ui_TableMaker.h"
#include "RenderArea.h"

class TableMaker : public QMainWindow
{
    Q_OBJECT

public:
    TableMaker(QWidget *parent = nullptr);
    void mousePressEvent(QMouseEvent* e) override;
    ~TableMaker();

private:
    
    RenderArea* renderArea;
    QLabel* statusMsg = new QLabel;
    Ui::TableMakerClass ui;
};

渲染区域.cpp:

#include "RenderArea.h"

RenderArea::RenderArea(QWidget* parent): QWidget(parent) {
    brush.setColor(tableColor);
    pen.setBrush(brush);
}

void RenderArea::addNewTable(QPoint p) {
    QRect* rec = new QRect(p, QSize(100, 100));
    recs.push_back(rec);
    this->update();
}

QSize RenderArea::sizeHint() const {
    return QSize(100, 100);
}

void RenderArea::paintEvent(QPaintEvent* e) {
    QWidget::paintEvent(e);
    QPainter p(this);
    p.setPen(pen);
    p.setBrush(brush);
    for (QRect* r : recs) {
        p.drawRect(*r);
    }
}

渲染区域.h:

#include <Qtwidgets>
#include "tableWidget.h"

class RenderArea : public QWidget {

    Q_OBJECT

public:
    explicit RenderArea(QWidget* parent = nullptr);
    void addNewTable(QPoint p);

protected:
    QSize sizeHint() const override;
    void paintEvent(QPaintEvent* e) override;

private:
    QColor tableColor = QColor(0, 0, 255);
    QBrush brush;
    QPen pen;
    QVector<QRect*> recs;
};

paintEvent
/绘画是如何工作的?我尝试阅读有关
QPaintEvent
的文档,似乎我正确地覆盖了
paintevent

这里的另一篇文章提到必须重新实现

sizeHint
,但正如你在下面看到的,我已经做到了,但它仍然不起作用。

c++ qt qwidget qpainter paintevent
1个回答
0
投票

说明:

paintEvent
确实被调用(在提供的代码中),您可以使用
qDebug()
:

进行检查
void RenderArea::paintEvent(QPaintEvent* e)
{
    QWidget::paintEvent(e);

    QPainter p(this);

    p.setPen(pen);
    p.setBrush(brush);

    //outputs: Qt::NoBrush
    qDebug()<<p.brush().style();
    //outputs: "#0000ff"
    qDebug()<<p.brush().color().name();
    //outputs: "#0000ff"
    qDebug()<<p.pen().color().name()<<"\n";

    for (QRect* r : recs)
    {
        //list gets bigger with every mouse press
        qDebug()<<r;
        p.drawRect(*r);
    }
}

问题是矩形是用没有设置样式的画笔绘制的。

来自 Qt 文档:QBrush 类

画笔 style() 使用 Qt::BrushStyle 枚举定义填充图案。默认画笔样式是Qt::NoBrush(取决于您构建画笔的方式)。这种风格告诉画家不要填充形状。


解决方案:

你只需要对

RenderArea
ctor 做一点补充:

RenderArea::RenderArea(QWidget* parent): QWidget(parent)
{
    //set brush style
    brush.setStyle(Qt::SolidPattern);
    brush.setColor(tableColor);
    pen.setBrush(brush);
}

结果:

© www.soinside.com 2019 - 2024. All rights reserved.