我试图在每次单击鼠标时在鼠标位置绘制一个矩形。
目前设置如下:
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
,但正如你在下面看到的,我已经做到了,但它仍然不起作用。
说明:
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);
}
结果: