tags:

views:

2089

answers:

3

I have started learning Qt recently.
I did not get quite clear how can I paint using QPainter class. Let`s say I want just to place a few points in the window:


class PointDrawer: public QWidget {
    Q_OBJECT
private:
    QPainter p;
public:
    PointDrawer(QWidget* obj=0): QWidget(obj), p(this) {}
    virtual void paintEvent(QPaintEvent*) {
     p.setPen(QPen(Qt::black, 3));
     int n = 8;
     while(...) {
      qreal fAngle = 2 * 3.14 * i / n;
      qreal x = 50 + cos(fAngle) * 40;
      qreal y = 50 + sin(fAngle) * 40;
      p.drawPoint(QPointF(x, y));
                        i++;
     }
    }
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    PointDrawer drawer;

    drawer.resize(200, 200);
    drawer.show();

    return app.exec();
}

and after that I got nothing! Can you please tell me where I am wrong?

+3  A: 
void SimpleExampleWidget::paintEvent(QPaintEvent *)
{
     QPainter painter(this);
     painter.setPen(Qt::blue);
     painter.setFont(QFont("Arial", 30));
     painter.drawText(rect(), Qt::AlignCenter, "Qt");
}

http://doc.trolltech.com/4.4/qpainter.html

Ronny
A: 

You need to initialize the painter with the widget you want to paint on.
Usually this is done using the c'tor which takes a QPaintDevice but you can also do it by calling begin().

shoosh
+3  A: 

I think the problem is your QPainter initialization.

You could just create the QPainter like in hydroes' answer, it would look like this then:

class PointDrawer: public QWidget {
    Q_OBJECT
public:
    PointDrawer(QWidget* obj=0): QWidget(obj) {}
    virtual void paintEvent(QPaintEvent*) {
        QPainter p(this)
        p.setPen(QPen(Qt::black, 3));
        int n = 8;
        while(...) {
                qreal fAngle = 2 * 3.14 * i / n;
                qreal x = 50 + cos(fAngle) * 40;
                qreal y = 50 + sin(fAngle) * 40;
                p.drawPoint(QPointF(x, y));
                        i++;
        }
    }
}

It could also use something like this, but I don't really recommend it (I just prefer the other solution):

class PointDrawer: public QWidget {
    Q_OBJECT
private:
    QPainter p;
public:
    PointDrawer(QWidget* obj=0): QWidget(obj) {}
    virtual void paintEvent(QPaintEvent*) {
        p.begin(this);
        p.setPen(QPen(Qt::black, 3));
        int n = 8;
        while(...) {
                qreal fAngle = 2 * 3.14 * i / n;
                qreal x = 50 + cos(fAngle) * 40;
                qreal y = 50 + sin(fAngle) * 40;
                p.drawPoint(QPointF(x, y));
                        i++;
        }
        p.end();
    }
}

The QPainter::begin(this) and QPainter::end() calls are essential in the second example. In the first example, you can think of QPainter::begin(this) being called in the constructor and QPainter::end() in the destructor

For the reason, I'm guessing: As QPaintDevices are usually double buffered in QT4, QPainter::end() might be where the image is transferred to the graphic memory.

Caotic