Event trigger for PaintEvent in "Basic Drawing Example"



  • Hello again,

    i´m experimenting on the "Basic Drawing Example"
    http://qt-project.org/doc/qt-4.8/painting-basicdrawing.html
    and try to find my way in.

    What i don´t understand is how this thing with the PaintEvent works. Is it triggered by the "update();" call?

    Greez, Moe



  • Yes, it triggered by calling the update() method. PaintEvent(...) method is virtual method this gets called when you show(..) the widget. If you want to call this method again, you need to call update() method. I suggest you look at how to write custom widgets. This will help you.



  • Think i got it.
    It looks like the painter is doing a "clear screen" with every PaintEvent. But when i want to draw a graph by using a timer SIGNAL for example this clearing is not so good. Can prevent this?



  • Can you provide more details ? May be code snippet on what you are trying would help us to help you.



  • Ok,

    i have broken down the Basic Drawing Example to the very lowest basics. i removed all the comboboxes and the multiple drawing of the selected shape. The only thing it does when the window.cpp´s constructor is called is to draw a polygon and afterwards a line of dots by
    "for(int i=0; i<20; i++)renderArea->setDot(i);"
    So i set up a method in rederarea.cpp called setDot().

    But the polygon is "overpainted" and from the line of Dots there´s only one. You can see a tiny little black pixel in the left upper corner.

    main.cpp
    @#include "window.h"

    #include <QApplication>

    int main(int argc, char *argv[])
    {
    Q_INIT_RESOURCE(basicdrawing);

    QApplication app(argc, argv);
    Window window;
    window.show();
    return app.exec&#40;&#41;;
    

    }@

    window.cpp
    @#include "renderarea.h"
    #include "window.h"

    #include <QtWidgets>

    const int IdRole = Qt::UserRole;

    Window::Window()
    {
    renderArea = new RenderArea;

    //QGridLayout *mainLayout = new QGridLayout;
    mainLayout = new QMainWindow;
    win = new QWidget;
    layout = new QHBoxLayout(win);
    layout->addWidget(renderArea);
    
    setCentralWidget(win);
    brushChanged();
    for(int i=0; i<20; i++)renderArea->setDot(i);
    setWindowTitle(tr("Basic Drawing"));
    

    }

    void Window::brushChanged()
    {

        QLinearGradient linearGradient(0, 0, 100, 100);
        linearGradient.setColorAt(0.0, Qt::white);
        linearGradient.setColorAt(0.1, Qt::red);
        linearGradient.setColorAt(1.0, Qt::blue);
        renderArea->setBrush(linearGradient);
    

    }@

    window.h
    @#ifndef WINDOW_H
    #define WINDOW_H

    #include <QWidget>
    #include <QMainWindow>
    #include <QHBoxLayout>

    class QCheckBox;
    class QComboBox;
    class QLabel;
    class QSpinBox;

    class RenderArea;

    class Window : public QMainWindow//QWidget
    {
    Q_OBJECT

    public:
    Window();

    private slots:

    void brushChanged();
    

    private:
    RenderArea renderArea;
    QLabel shapeLabel;
    QWidget
    win;
    QMainWindow
    mainLayout;
    QHBoxLayout* layout;
    };

    #endif // WINDOW_H@

    enderarea,cpp
    @#include "renderarea.h"

    #include <QPainter>

    RenderArea::RenderArea(QWidget *parent)
    : QWidget(parent)
    {
    shape = Polygon;
    antialiased = false;
    transformed = false;
    //pixmap.load(":/images/qt-logo.png");

    setBackgroundRole(QPalette::Base);
    setAutoFillBackground(true);
    x = 0;
    

    }

    QSize RenderArea::minimumSizeHint() const
    {
    return QSize(100, 100);
    }

    QSize RenderArea::sizeHint() const
    {
    return QSize(400, 200);
    }

    void RenderArea::setShape(Shape shape)
    {
    this->shape = shape;
    update();
    }

    void RenderArea::setPen(const QPen &pen)
    {
    this->pen = pen;
    update();
    }

    void RenderArea::setBrush(const QBrush &brush)
    {
    this->brush = brush;
    update();
    }

    void RenderArea::setAntialiased(bool antialiased)
    {
    this->antialiased = antialiased;
    update();
    }

    void RenderArea::setTransformed(bool transformed)
    {
    this->transformed = transformed;
    update();
    }

    void RenderArea::setDot(int yin)
    {
    shape = dot;
    y = yin;
    x++;
    update();
    }

    void RenderArea::paintEvent(QPaintEvent * /* event */)
    {
    static const QPoint points[5] = {
    QPoint(0, 15),
    QPoint(15, 0),
    QPoint(30, 0),
    QPoint(45, 15),
    QPoint(22, 30)
    };

    QPainter painter(this);
    painter.setPen(pen);
    painter.setBrush(brush);
    if (antialiased)
        painter.setRenderHint(QPainter::Antialiasing, true);
    painter.save();
    switch(shape)
    {
    case Polygon:
        painter.translate(50, 50);
        painter.drawPolygon(points, 5);
        painter.translate(-50, -50);
        for(int i=0; i<200; i++)painter.drawPoint(70+i,70);//painting the black line
        break;
    
      case dot:
        painter.drawPoint(x, y);
    }
       painter.restore();
    painter.setRenderHint(QPainter::Antialiasing, false);
    painter.setBrush(Qt::NoBrush);
    

    }@

    renderarea.h
    @#ifndef RENDERAREA_H
    #define RENDERAREA_H

    #include <QBrush>
    #include <QPen>
    #include <QPixmap>
    #include <QWidget>

    class RenderArea : public QWidget
    {
    Q_OBJECT

    public:
    enum Shape { Line, Points, Polyline, Polygon, Rect, RoundedRect, Ellipse, Arc,
    Chord, Pie, Path, Text, Pixmap, dot };

    RenderArea(QWidget *parent = 0);
    
    QSize minimumSizeHint() const;
    QSize sizeHint() const;
    

    public slots:
    void setShape(Shape shape);
    void setPen(const QPen &pen);
    void setBrush(const QBrush &brush);
    void setAntialiased(bool antialiased);
    void setTransformed(bool transformed);
    void setDot(int yin);

    protected:
    void paintEvent(QPaintEvent *event);

    private:
    Shape shape;
    QPen pen;
    QBrush brush;
    bool antialiased;
    bool transformed;
    QPixmap pixmap;
    int x, y;
    };

    #endif // RENDERAREA_H@



  • You are starting with very hard example and tweaking. You can try something as simple as this and try to understand how things happen.
    @==== main.cpp=====
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MyStar w;
    w.show();
    return a.exec();
    }
    == MyStar.h and MyStar.cpp =====
    class MyStar : public QWidget
    {
    Q_OBJECT

    public:
    MyStar(QWidget *parent = 0);
    ~MyStar();

    public slots :
    void drawmeagain();

    protected :
    void paintEvent(QPaintEvent *);

    private :
    int x;
    };

    MyStar::MyStar(QWidget *parent)
    : QWidget(parent)
    {
    x=10;
    QTimer *tim = new QTimer;
    tim->setInterval(10);
    connect(tim,SIGNAL(timeout()),this,SLOT(drawmeagain()));
    tim->start();
    }

    void MyStar::drawmeagain() {
    x++;
    if (x > this->size().width())
    x = 10;
    update();
    }

    MyStar::~MyStar(){}

    void MyStar::paintEvent(QPaintEvent *){
    QPainter *painter = new QPainter(this);
    painter->setPen(Qt::blue);
    painter->setBrush(Qt::white);
    QRect rect(x,10,100,100);
    painter->drawEllipse(rect);

     QRect rect1(110,10,100,100);
     QPen pen;
     pen.setWidth(2);
     pen.setColor(QColor(100,100,100));
     painter->setPen(pen);
     painter->setBrush(QColor(150,200,200));
     painter->drawRect(rect1);
    

    }
    @



  • Yeay, thank you, that looks much more clearly ;-)

    I inserted a "delete painter;" at the bottom of the Event. First i tried to make a normal local variable
    "QPainter painter;" and of course change the pointeraccess "->" to "." to But somehow he didn´t like it.



  • Cool. Hope it solved your issue. You can put the issue to SOLVED state.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.