QLabel 上的绘图点错误
Error with drawing point on QLabel
我正在尝试像这样在 Qt
中利用 QLabel
:
paintscene.h:
class PaintScene : public QWidget
{
Q_OBJECT
public:
PaintScene(QWidget* parent = NULL);
QVector<QLabel*> _layers;
QColor _color;
int _width;
void mousePressEvent(QMouseEvent* event);
private slots:
void updateWidth();
};
paintscene.cpp:
PaintScene::PaintScene(QWidget* parent) : QWidget(parent)
{
_width = 10;
_color = Qt::red;
QLabel* inital = new QLabel(this);
inital->setStyleSheet("QLabel { background-color : white; }");
_layers.push_back(inital);
QGridLayout* layout = new QGridLayout();
layout->addWidget(inital, 1, 1, 1, 1);
this->setLayout(layout);
}
void PaintScene::mousePressEvent(QMouseEvent *event)
{
QImage tmp = _layers.back()->pixmap()->toImage();
QPainter painter(&tmp);
QPen paintpen(_color);
paintpen.setWidth(_width);
painter.setPen(paintpen);
painter.drawPoint(event->x(), event->y());
_layers.back()->setPixmap(QPixmap::fromImage(tmp));
}
需要该列表,因为我想用图层(QLabel
- 一个单独的图层)来实现工作。
但是,我得到一个错误,程序终止。错误发生在 QImage tmp = _layers.back()->pixmap()->toImage();
行。
是什么导致了这种情况?这怎么能解决?也许层使用不同的东西,而不是 QLabel
?
来自 Qt docs 的 QLabel::pixmap()
:
This property holds the label's pixmap
If no pixmap has been set this will return 0.
...所以当你这样做时:
QImage tmp = _layers.back()->pixmap()->toImage();
pixmap()
返回 NULL(因为 QLabel 尚未在其上设置任何 QPixmap),然后您尝试取消引用该 NULL 指针以在其上调用 toImage()
,因此崩溃.
为避免崩溃,请勿尝试从 NULL QPixmap 指针创建 QImage。
我怀疑您想调用 grab()
而不是 pixmap()
-- grab()
将为您创建一个包含 QLabel 视觉外观的 QPixmap。但是,更好的方法是完全避免乱用 QPixmaps
;相反,创建你自己的 QLabel
class 的 subclass,并覆盖其 paintEvent(QPaintEvent *)
方法以首先调用 QLabel::paintEvent(e)
然后使用 QPainter 绘制之后的附加点。这将更容易实现,并且在运行时也更高效。
@Jeremy Friesner关于错误的原因是正确的,没有QPixmap这将是空的,在我的回答中我会展示一个可能的解决方案
void PaintScene::mousePressEvent(QMouseEvent *event)
{
QLabel *label = _layers.back();
const QPixmap *pix= label->pixmap();
QPixmap pixmap;
if(pix)
pixmap = *pix;
else{
pixmap = QPixmap(label->size());
pixmap.fill(Qt::transparent);
}
QPainter painter(&pixmap);
QPen paintpen(_color);
paintpen.setWidth(_width);
painter.setPen(paintpen);
painter.drawPoint(event->pos());
painter.end();
label->setPixmap(pixmap);
}
我正在尝试像这样在 Qt
中利用 QLabel
:
paintscene.h:
class PaintScene : public QWidget
{
Q_OBJECT
public:
PaintScene(QWidget* parent = NULL);
QVector<QLabel*> _layers;
QColor _color;
int _width;
void mousePressEvent(QMouseEvent* event);
private slots:
void updateWidth();
};
paintscene.cpp:
PaintScene::PaintScene(QWidget* parent) : QWidget(parent)
{
_width = 10;
_color = Qt::red;
QLabel* inital = new QLabel(this);
inital->setStyleSheet("QLabel { background-color : white; }");
_layers.push_back(inital);
QGridLayout* layout = new QGridLayout();
layout->addWidget(inital, 1, 1, 1, 1);
this->setLayout(layout);
}
void PaintScene::mousePressEvent(QMouseEvent *event)
{
QImage tmp = _layers.back()->pixmap()->toImage();
QPainter painter(&tmp);
QPen paintpen(_color);
paintpen.setWidth(_width);
painter.setPen(paintpen);
painter.drawPoint(event->x(), event->y());
_layers.back()->setPixmap(QPixmap::fromImage(tmp));
}
需要该列表,因为我想用图层(QLabel
- 一个单独的图层)来实现工作。
但是,我得到一个错误,程序终止。错误发生在 QImage tmp = _layers.back()->pixmap()->toImage();
行。
是什么导致了这种情况?这怎么能解决?也许层使用不同的东西,而不是 QLabel
?
来自 Qt docs 的 QLabel::pixmap()
:
This property holds the label's pixmap
If no pixmap has been set this will return 0.
...所以当你这样做时:
QImage tmp = _layers.back()->pixmap()->toImage();
pixmap()
返回 NULL(因为 QLabel 尚未在其上设置任何 QPixmap),然后您尝试取消引用该 NULL 指针以在其上调用 toImage()
,因此崩溃.
为避免崩溃,请勿尝试从 NULL QPixmap 指针创建 QImage。
我怀疑您想调用 grab()
而不是 pixmap()
-- grab()
将为您创建一个包含 QLabel 视觉外观的 QPixmap。但是,更好的方法是完全避免乱用 QPixmaps
;相反,创建你自己的 QLabel
class 的 subclass,并覆盖其 paintEvent(QPaintEvent *)
方法以首先调用 QLabel::paintEvent(e)
然后使用 QPainter 绘制之后的附加点。这将更容易实现,并且在运行时也更高效。
@Jeremy Friesner关于错误的原因是正确的,没有QPixmap这将是空的,在我的回答中我会展示一个可能的解决方案
void PaintScene::mousePressEvent(QMouseEvent *event)
{
QLabel *label = _layers.back();
const QPixmap *pix= label->pixmap();
QPixmap pixmap;
if(pix)
pixmap = *pix;
else{
pixmap = QPixmap(label->size());
pixmap.fill(Qt::transparent);
}
QPainter painter(&pixmap);
QPen paintpen(_color);
paintpen.setWidth(_width);
painter.setPen(paintpen);
painter.drawPoint(event->pos());
painter.end();
label->setPixmap(pixmap);
}