Solved Can't paint points on my widget
-
Hi
You are ONLY allowed to paint in paintEvent function so you must add the function
to your classPointViewer:.paintEvent(QPaintEvent *e) {
QPen pen(Qt::green, z, Qt::SolidLine, Qt::RoundCap);
QPainter painters(this); <<<<<<<<<<<<<<<<< notice the change.
painter.begin(ui->liveFeedWidget);
painter.setPen(pen);
painter.drawPoint(x,y);
painter.end();
}To easy add it.
Go to your .h file, right click on class PointViewer, select refactor menu and
insert virtual base function. then find in list.
and then press ok.
-
@mrjj So first off, the example code provided by Qt, "basicdrawing" doesn't use this at all, so how is it able to work?
Second, if I do as you suggest, I can only paint once. I need to be able to repaint the points when new data is provided.
-
@graniteDev
show me link. most likely it paints on image. (which is only case where allowed outside)
you can call widget->update() at any time to repaint. -
@mrjj
Qt example I am trying to follow from: https://doc.qt.io/qt-5/qtwidgets-painting-basicdrawing-example.htmlHow do I pass parameters into the function? I suppose I could set global variables with the data, and then call that data from the override "paintEvent" but I'd prefer to just pass it in by reference if I can.
-
@graniteDev
Ah. well it paints via
void RenderArea ::paintEvent(QPaintEvent *event) override;You cant change paintEvent signature so you will have to copy the points to member variables
and then call update and in paintEvent use those member variables.
No reason for global vars. just let PointViewer store them and let paintEvent use those member vars.
something like
PointViewer::ShowPoint(int x, int y, int z) {
m_x=x; m_y=y; m_z=z;
update();
}and paintEvent uses m_x,m_y etc.
you could let it point to original data in other class if its heavy but for some ints i dont think it matters. -
@mrjj Yes, that's what I meant to say... I think of member variables as global because of their scope, but I didn't not mean global to the whole application.
I tried the code as you provided, but still nothing happened.
void PointViewer::paintEvent(QPaintEvent *) { QPen pen(Qt::green, 20, Qt::SolidLine, Qt::RoundCap); QPainter painter(this); painter.begin(ui->liveFeedWidget); painter.setPen(pen); painter.drawPoint(100,200); painter.end(); }
-
@mrjj I usually create a new class, MyCanvas, and promote the Widget to it, mainly because I what to capture mouse and other events. Which is the Qt preferred way?
-
@ofmrew
Well that is indeed a good way as it allows both design time handling and
custom drawing. I think PointViewer is sort of a MyCanvas type. -
@graniteDev
Did you use override ?
so we ar sure its correct ?
try put qDebug() << "im in paint";
to check it is indeed called.Also what is
begin(ui->liveFeedWidget);
that looks wrong.
Are you trying to draw to multiple widgets from PointViewer ?
try with
painter.begin();also, make sure widget is at least 100,200 in size.
-
begin(ui->liveFeedWidget);
is in the code you provided. That is the widget within my ui that I want to paint to. I don't want to paint directly to "this" as "this" has buttons, and labels. I want to paint to the QWidget inside it's form ui->liveFeedWidget
My header file
protected: void paintEvent(QPaintEvent *) override;
My source file
void PointViewer::paintEvent(QPaintEvent *) { QPen pen(Qt::green, 20, Qt::SolidLine, Qt::RoundCap); QPainter painter(this); painter.begin(ui->liveFeedWidget); painter.setPen(pen); painter.drawPoint(100,200); painter.end(); }
-
Hi
Sorry didnt spot it before.
So goal is to paint from
PointViewer to ui->liveFeedWidget
or IS the ui->liveFeedWidget a PointViewer instance?If liveFeedWidget is completely other widget , then it need to have the paintEvent and not
PointViewer.You cannot paint from other widget to other widgets.
-
@mrjj Ah, ok
So, liveFeedWidget is a widget I added to the PointViewer class's pointviewer.ui form file. Is it possible to access it from PointViewer and override it's paintEvent without my making another class and promoting it to that class? I don't like to make extra classes if I can avoid it, it makes the code harder to follow for those that come behind me. Self contained classes are best if it can be achieved.
-
@graniteDev said in Can't paint points on my widget:
liveFeedWidget
But is it a custom control ?
What type is it ? -
@mrjj it's just a QWidget
-
@graniteDev
Ok, you could use QLabel and paint to a pixmap and assign pixmap
to the label.
Else only way is to add paintEvent to custom widget.
PaintEvent is virtual and only way to override is to subclass. -
This still didn't work
void PointViewer::paintEvent(QPaintEvent *) { QPen pen(Qt::green, 20, Qt::SolidLine, Qt::RoundCap); QPainter painter(this); painter.setPen(pen); painter.drawPoint(100,200); }
I'm expecting, that at 20 pixels I should be able to see SOME dot on the screen, but I see nothing
-
There should be a point at 100,200
insert qDebug() to be sure its called.
If you really dont want a custom widget for drawing, you can do like
QPixmap pix(200, 200); pix.fill(Qt::blue); QPainter painter(&pix); painter.drawpoint(50, 50); ui->label->setPixmap(pix);
-
@mrjj WE HAVE A DOT!!!!!
UGH, I have no idea why the previous code did not work. But this looks like it does. I'm going to see if this works for me. I'm hoping that as it's updated with new data it does not flicker.
-
@graniteDev
\o/
Long live the DOT.Qwidgets uses double buffer system internally so often there is no flicker.
Did you use pixmap or paintEvent ?
-
@mrjj Crud, now I have a different problem, how do I draw different points with different sizes at the same time? Drawing many points of the same size is easy, that's readily handled, but I need to draw different sized points to denote how far or near a marker is that the point represents.