Qt4 How to draw inside a widget?
Solution 1
You need to override paintEvent() and do your painting there. You don't really need the begin()
and end()
. Declare the painter with
QPainter painter(this);
The constructor will handle begin()
, and end()
will be called when the painter
object goes out of scope and is destroyed.
You also won't need the click event to trigger the painting. paintEvent()
will be called whenever the widget needs to draw itself. You could use the the button click to toggle a boolean that the paintEvent()
checks to determine whether or not it should display the rectangle and arc. Just make sure you call update()
after you toggle the variable.
void Widget::on_pushButton_clicked()
{
drawShapes = !drawShapes;
update();
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
if(drawShapes)
{
QRectF rectangle(10.0, 20.0, 80.0, 60.0);
int startAngle = 30 * 16;
int spanAngle = 120 * 16;
painter.drawArc(rectangle, startAngle, spanAngle);
}
}
UPDATE:
To avoid having to override the paintEvent()
of a widget, you could use a QLabel
and assign a pixmap to it and paint to that. Note: As far as I can tell, you will need to set the pixmap each time you modify it.
void MainForm::slot_buttonClick()
{
QPixmap pixmap(100,100);
pixmap.fill(QColor("transparent"));
QPainter painter(&pixmap);
painter.setBrush(QBrush(Qt::black));
painter.drawRect(10, 10, 100, 100);
label.setPixmap(pixmap);
}
Solution 2
If you overwrite the paint-method as described by Arnold Spence, you should call the parent's paintEvent or you end up with a widget that only shows your rectangle on a white background.
Astronavigator
Updated on May 03, 2020Comments
-
Astronavigator about 4 years
Qt4, QtCreator
I am trying to draw inside Widget:
void Widget::on_pushButton_clicked() { QPainter painter; painter.begin(ui->label); QRectF rectangle(10.0, 20.0, 80.0, 60.0); int startAngle = 30 * 16; int spanAngle = 120 * 16; painter.drawArc(rectangle, startAngle, spanAngle); painter.end(); }
But when I press button nothing happens.
How to do this right way?
-
Astronavigator over 13 yearsIs there any way to paint without overriding? Or is there any component on which i can draw without any event, like TImage or TForm or any other component containing TCanvas in VCL(Delphi)? (In Delphi could just write Form1.Canvas.Circle(...) whenever i need it, not only inside onpaint event)
-
Arnold Spence over 13 yearsI've never actually tried drawing on a widget with code external to the widget but QWidget does inherit PaintDevice so it should be possible.
-
Arnold Spence over 13 yearsScratch that, from the docs for QPainter.. "Warning: When the paintdevice is a widget, QPainter can only be used inside a paintEvent() function or in a function called by paintEvent(); that is unless the Qt::WA_PaintOutsidePaintEvent widget attribute is set. On Mac OS X and Windows, you can only paint in a paintEvent() function regardless of this attribute's setting."
-
Arnold Spence over 13 yearsYou could use a QLabel and QPixmap, draw on the pixmap and assign it to the label. I added an update with code above.