Solved Can't paint points on my widget
-
@graniteDev
maybe i didnt understand properlyCurrently one x,y,z is painted. if you call
paintMarkers again, it will only show the last point.
If plan it to show many sets of x,y,z, you must handle that.
One options is to move pixmap to member and not clear it in
paintMarkers. that way you can draw over/keep the other points.
That is the goal correct ?
To draw many 3d points on same pixmap?
Alternatively, it should store the points and redraw all each time. -
@mrjj Yes that is the goal, to have many points on a member variable pixMap that are all a unique size and position as determined by their x-y-z values.
-
@mrjj Interesting, so I added this code to my header file:
QPixmap m_pix;
This to my constructor:
PointViewer::PointViewer(QWidget *parent) : QWidget(parent), ui(new Ui::PointViewer), m_pix(800,600) { ui->setupUi(this); qDebug() << "test 11"; m_pix.fill(Qt::black); ui->pointViewerLabel->setPixmap(m_pix); }
And this to the paintMarkers function
void PointViewer::paintMarkers(int x, int y, int z) { QPen pen(Qt::green, z, Qt::SolidLine, Qt::RoundCap); QPainter painter(&m_pix); painter.setPen(pen); painter.drawPoint(x,y); ui->pointViewerLabel->update(); }
and then called paintMarkers() with a button
void PointViewer::on_pushButton_clicked() { paintMarkers(200, 300, 50); }
and this did not work, so I'm not sure how to use a pixmap as a member variable and still get this to work. The pixmap did appear as a black 800x600 rectangle, so that part is working, but no green dot.
Thank you for you help btw!
-
Hi
You are most welcome.
I think the error is
ui->pointViewerLabel->update();
as that would just make it draw the copy of pixmap it has.
you must call setPixmap again. (no need for update as that it will do it self) -
oh...ok so
ui->pointViewerLabel->update() doesn't work, it needs to be ui->pointViewerLabel->setPixmap(m_pix); -
@graniteDev
Yes as update will just make it draw the COPY of the m_pix u give it in ctor. -
@mrjj Ok that is working , but I can't get anymore than one dot to appear. How do I add points to draw with different pens? I tried this, just to see if it would work - ideally I'll need to iterate through a list of points in the future...
QPen pen1(Qt::green, 50, Qt::SolidLine, Qt::RoundCap); QPen pen2(Qt::green, 10, Qt::SolidLine, Qt::RoundCap); QPainter painter(&m_pix); painter.setPen(pen1); painter.drawPoint(300,200); painter.setPen(pen2); painter.drawPoint(200,300); ui->pointViewerLabel->setPixmap(m_pix);
but I only got the first dot.
-
@graniteDev
Well lets first test if
void PointViewer::on_pushButton_clicked()
{
paintMarkers(200, 300, 50);
paintMarkers(210, 300, 50);
paintMarkers(220, 300, 50);
}
does what we want. We could then add new paramter for size or color -
@graniteDev
Wont it be a green small dot in big green dot ?
try with red
QPen pen1(Qt::green, 50, Qt::SolidLine, Qt::RoundCap);
QPen pen2(Qt::red, 10, Qt::SolidLine, Qt::RoundCap);
QPainter painter(&m_pix);
painter.setPen(pen1);
painter.drawPoint(300,200);
painter.setPen(pen2);
painter.drawPoint(200,300);
ui->pointViewerLabel->setPixmap(m_pix); -
@mrjj OH yes, I must have had the same exact point specified, as I tried that before and it didn't work, however this code yielded
void PointViewer::on_pushButton_clicked() { paintMarkers(200, 300, 50); paintMarkers(250, 250, 40); paintMarkers(300, 200, 30); }
-
@graniteDev
Ok super.
So now i wondering if we could dovoid PointViewer::on_pushButton_clicked()
{
paintMarkers(200, 300, 50, Qt::red , 32);
paintMarkers(250, 250, 40, Qt::blue,128 );
paintMarkers(300, 200, 30, QColor(255,0,0), 64);
}so header/function be
void PointViewer::paintMarkers(int x, int y, int z, QColor dotColor, int dotSize)would that be good enough ?
and u need to use them of coursevoid paintMarkers(int x, int y, int z, QColor dotColor, int dotSize) { QPen pen(dotColor, dotSize, Qt::SolidLine, Qt::RoundCap); // could we use z to adjust dotSize? QPainter painter(&m_pix); painter.setPen(pen); painter.drawPoint(x,y); ui->pointViewerLabel->setPixmap(m_pix);
-
@mrjj Wow, ok this is working!! Thank you again so much for the help in understanding how to use these features.
I tried calling m_pix.fill(Qt::black); to clear m_pix to black again before painting new dots and this worked fine. However is this the most effective/efficient means of resetting m_pix before painting the new dots? I'll be dealing with live data at about ~50hz so I want to make this is as efficient as possible so that it looks live and fairly smooth to the user.
-
@graniteDev
Well fill is pretty fast and setPixmap(m_pix) even if it makes copy should be pretty fast too due to implicit sharing. But the downside of using this image approach is that it will be slightly more heavy than a custom paint event. However, since the pixmap acts as a caches you get free speed
upgrade since you dont need to draw all points.
But say u make pixmap 1920x1080, this might be too heavy so also depends on image size.
( it takes time for QLabel to draw pixmap)
Also on small pc its far more heavy than say on big fat i7 desktop one.so you might need a custom widget with paintEvent for optimal performance but depending on how many points and how big image must be, this might also work just fine even not the most
efficient way. -
@mrjj Ok, I'll test this first. If it's too slow, I'll try the custom class, although I'm concerned there as before in our attempts I couldn't get a paint event to occur on even PointViewer class.
-
@graniteDev
Well if it is too slow. come back and ill help you get paintEvent running.
Its not complicated and we can use almost same code except not using pixmap.
Would take maybe 10 mins to make it a custom control and promote the widget you have in UI to be
the new drawDots class.