QPainter does not work
-
I want to draw line each call my function and delete old lines.
void draw(QPointF firstPosOfForm, QPointF posOfForm) { //_container is QWidget on UI QPainter painter(_container); painter.setRenderHint(QPainter::Antialiasing); QLine line1(firstPosOfForm.x(), 0, firstPosOfForm.x(), _container->height()); QLine line2(posOfForm.x(), 0, posOfForm.x(), _container->height()); painter.eraseRect(_container->rect()); painter.drawLine(line1); painter.drawLine(line2); }
Step 1 : Click and take first position.
Step 2: move the cursor.
Step 3: release mouse button and take last position.
Step 4: send Qpoint' s with function.
Step 5: draw linesNote : container contains a QImage. and these lines must be front the QImage.
How could I do it ?
-
@Joe-von-Habsburg said in QPainter does not work:
How could I do it ?
What? You wrote that QPainter is not working - you can only paint on a widget inside it's paintEvent().
-
In the paintEvent, you want to just fully draw the full state of what the widget should look like Right Now. Not some accumulation where you previously drew old lines and now you erase some of them and keep recycling a QImage buffer.
in paintEvent you do something like
{ auto p = new QPainter(this); p.drawImage(the_background); // You say you want lines over the image, so draw it first p.drawLine(...); //wherever you currently want your lines based on mosue position or whatever. delete p; // Never needed to mess around with erasing anything, because only drew the lines we need to see right now. }
-
@wrosecrans no need to allocate the painter on the heap. This just make the code more complex for no benefits.
-
@Christian-Ehrlicher said in QPainter does not work:
What? You wrote that QPainter is not working - you can only paint on a widget inside it's paintEvent().
In my function, it did not work. Should I use paintEvent ?
@SGaist said in QPainter does not work:
no need to allocate the painter on the heap. This just make the code more complex for no benefits.
Thank you
-
@Christian-Ehrlicher said in QPainter does not work:
paintEvent().
How can I send qpoints to paintEvent ? Could you give code example ?
-
@Joe-von-Habsburg said in QPainter does not work:
How can I send qpoints to paintEvent ?
You don't send anything. Just store them in your class.
-
@Christian-Ehrlicher said in QPainter does not work:
You don't send anything. Just store them in your class.
I wrote basic code. I send points and update widget. Lines have been drawn but I draw there QImage currently, and lines deleted
class MyClass : public QObject{ MyClass(){ widget = new Widget(parentWidget) connect(this, &MyClass:sendPoints, widget, &Widget:takePointsFromClass) } public slots: void takePoints(QPointF first, QPointF last){ emit sendPoints(first, last); } signals: void sendPoints(QPointF first, QPointF last); private: Widget *widget; } class Widget : public QWidget { Widget(); public slots: void takePointsFromClass(QPointF first, QPointF last){ _first.setX(first.x()); _first.setY(first.y()); _last.setX(last.x()); _last.setY(last.y()); _canDraw = true; update(); } protected: void paintEvent(QPaintEvent *event) { if(_canDraw ){ QPainter painter(this); QLine line1(_first.x(), 0, _first.x(), height()); QLine line2(_last.x(), 0, _last.x(), height()); painter.eraseRect(rect()); painter.drawLine(line1); painter.drawLine(line2); _canDraw = false; } }` private: bool _canDraw = false; QPointF _first; QPointF _last;
-
Simple example:
// widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); // QWidget interface protected: void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void paintEvent(QPaintEvent *event); private: QImage mBackground; QPointF mFrom; QPointF mTo; }; #endif // WIDGET_H
// widget.cpp #include "widget.h" #include <QPaintEvent> #include <QPainter> Widget::Widget(QWidget *parent) : QWidget(parent) { mBackground.load("/tmp/paint/background.jpeg"); } Widget::~Widget() { } void Widget::mousePressEvent(QMouseEvent *event) { mFrom = event->position(); mTo = mFrom; } void Widget::mouseReleaseEvent(QMouseEvent *event) { mTo = event->position(); update(); } void Widget::paintEvent(QPaintEvent *event) { QPainter p(this); p.drawImage(event->rect(), mBackground); if (mFrom != mTo) { QPen pen(Qt::red); pen.setWidth(3); p.setPen(pen); p.drawLine(mFrom, mTo); } p.end(); }
-
@ChrisW67 said in QPainter does not work:
void Widget::paintEvent(QPaintEvent *event)
{
QPainter p(this);
p.drawImage(event->rect(), mBackground);
if (mFrom != mTo) {
QPen pen(Qt::red);
pen.setWidth(3);
p.setPen(pen);
p.drawLine(mFrom, mTo);
}
p.end();
}I will try, Thank you :)
@ChrisW67 In my code, QImage is constantly refreshing and that is delete my lines.
-
@Joe-von-Habsburg said in QPainter does not work:
QImage is constantly refreshing and that is delete my lines
What does this mean?
-
@Joe-von-Habsburg
If the image changes, for whatever reason, you have to redraw the lines when you redraw the background. Which yourpaintEvent()
seems to do. So unless you are changing the image somewhere else I don't see how you get a new image but no lines. -
@Joe-von-Habsburg said in QPainter does not work:
@ChrisW67 In my code, QImage is constantly refreshing and that is delete my lines.
Then you are saying that mBackground in my example is changing. When you change it, call update().
-
@jsulm said in QPainter does not work:
What does this mean?
I take data each 100ms maybe, and I draw QImage with that data. and my QIMage refreshing always
@JonB said in QPainter does not work:
you have to redraw the lines when you redraw the background.
I draw but it likes be a gif. I want to see a const line not a gif.
-
@Joe-von-Habsburg
I don't know what you are saying.The only code of yours I see which draws an image is the
drawImage()
in yourpaintEvent()
, and that also draws the line on top of it. So I don't see where you are changing the image without drawing the line.If you have different code from what you have shown we cannot guess.
-
@JonB said in QPainter does not work:
The only code of yours I see which draws an image is the drawImage() in your paintEvent(), and that also draws the line on top of it. So I don't see where you are changing the image without drawing the line.
If you have different code from what you have shown we cannot guess.MyClass (){ widget= new Widget(containerImage->parentWidget()); widget->setFixedSize(containerImage->parentWidget()->size()); _image = new QImage(_containerImage->width(), _containerImage->height(), QImage::Format_RGB32); } void draw(...) { //_containerImage is a QLabel for(int x = 0; x < _image->width(); x++){ for(int y = _image->height() - 1; y > 0; y--){ _image->setPixel(x, y , _image->pixel(x, y-1)); } } double step = static_cast<double>(sample) / (_containerImage->width()); QList<double> list; for(int i = 0; i < _containerImage->width(); i++){ list.append(step * i); } for(int i = 0; i < list.size(); i++){ int ii = round(list.at(i)); _image->setPixel(i, 0, getColor(ssd.samples[ii + startPoint].toDouble()).rgb()); } _containerImage->setPixmap(QPixmap::fromImage(*_image)); emit setPoints(_first, _last); }
-
@Joe-von-Habsburg
I have no idea what_containerImage
is or how this has any relationship at all to yourWidget::paintEvent()
, when that is called, or whatmBackground
is compared to_containerImage
....If you want help with code you have you have to actually show it. Revealing extra bits of code you have over time does not help.
-
@Joe-von-Habsburg My example recast with a changing background:
// widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); // QWidget interface protected: void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void paintEvent(QPaintEvent *event); private slots: void setBackground(); private: QImage mBackground; QPointF mFrom; QPointF mTo; }; #endif // WIDGET_H
// widget.cpp #include "widget.h" #include <QPaintEvent> #include <QPainter> #include <QLinearGradient> #include <QRandomGenerator> #include <QTimer> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) , mBackground(500, 500, QImage::Format_RGB32) { setBackground(); QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, &Widget::setBackground); t->start(1000); } Widget::~Widget() { } void Widget::mousePressEvent(QMouseEvent *event) { mFrom = event->position(); mTo = mFrom; } void Widget::mouseReleaseEvent(QMouseEvent *event) { mTo = event->position(); update(); } void Widget::paintEvent(QPaintEvent *event) { QPainter p(this); p.drawImage(event->rect(), mBackground); if (mFrom != mTo) { QPen pen(Qt::red); pen.setWidth(3); p.setPen(pen); p.drawLine(mFrom, mTo); } p.end(); } void Widget::setBackground() { QPainter p(&mBackground); const QRectF rectf(mBackground.rect()); QLinearGradient grad(rectf.topLeft(), rectf.bottomRight()); grad.setColorAt(0, QColor::fromRgb(QRandomGenerator::global()->generate())); grad.setColorAt(1, QColor::fromRgb(QRandomGenerator::global()->generate())); p.fillRect(mBackground.rect(), QBrush(grad)); p.end(); update(); }