简体   繁体   中英

Qt : Having a single instance of QPainter object in a class

I am doing a project in Qt and there is an object QPainter which is declared as :

 QPainter painter(this);

Where this points to the present class. My problem is that I need to declare this object such that it is accessible to the entire class functions.

If I declare it inside the constructor then its scope is not valid for other functions, and I cannot declare outside all function in my .cpp file as this variable doesn't make any sense.

So how can I declare my object such that it is accessible to all the functions?

Edit : Painter Code :

void MainWindow :: paintEvent(QPaintEvent * e)
{
    QMainWindow::paintEvent(e);
        if(1)
        {
           QPainter painter(this);
           QPen paintpen(Qt::red);
           paintpen.setWidth(5);
           QPoint p1;
           p1.setX(mFirstX);
           p1.setY(mFirstY);
           painter.setPen(paintpen);
           painter.drawPoint(p1);
         }

}

Mouse Event Code :

void MainWindow :: mousePressEvent(QMouseEvent *e)
{
    mFirstX=0;
    mFirstY=0;
    mFirstClick=true;
    mpaintflag=false;

    if(e->button() == Qt::LeftButton)
            {
                //store 1st point
                if(1)
                {
                    mFirstX = e->x();
                    mFirstY = e->y();
                    mFirstClick = false;
                    mpaintflag = true;
                    qDebug() << "First image's coordinates" << mFirstX << "," << mFirstY ;
                    update();

                }

            }
}

PROBLEM : I want to create the point but I don't want it to disappear from the widget(mainWindow). Here since the object is created during the paintEvent method each time the point that I am drawing is disappearing when the next point is drawn.

And if I declare it outside the paintEvent then I get the following error:

 QWidget::paintEngine: Should no longer be called  
 QPainter::begin: Paint device returned engine == 0, type: 1  
 QPainter::setPen: Painter not active

In general, declaring the QPainter object globally is not a good idea. It is better to construct it in the QWidget::paintEvent (where it will be active) and, as @Mat said, pass it (by reference) to the functions that need it.

In your particular case the point disappears because the widget is redrawn, not because the QPainter is destroyed. So the strategy should be to create and manage a buffer of points. Add a point to the buffer in a mouse event, eg QWidget::mousePressEvent (there do some management too, eg limiting the number of points) and in the paint event - paint all the points from the buffer.

Here is an oversimplified example which could easily be adapted for your specific purpose:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPainter>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);

protected:
    void mousePressEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);

private:
    QList<QPoint> m_points;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    QPalette p = QPalette();

    p.setColor(QPalette::Window, Qt::white);

    setPalette(p);
    setAutoFillBackground(true);
    resize(400, 400);
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    m_points.append(event->pos());

    update();
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    painter.setClipping(true);
    painter.setClipRect(event->rect());

    painter.setPen(QPen(Qt::red, 5));

    foreach (QPoint point, m_points) { painter.drawPoint(point); }
}

That's what class attributes are for :

class MyObject : public QObject {
    Q_OBJECT

public:
    MyObject(QObject *parent = 0) : QObject(parent), painter_(this) {
        // Other things if you need them
    }

    void aFunction() {
        // You can use painter_  here !!
    }
private :
    QPainter painter_;
}

In the private access specifier of your main window class in mainWindow.h, you could write this line

QPainter *painterPointer

creating a pointer accessible in all MainWindow slots. You could use that painterPointer as though it were any painter pointer initialised in any slot. However if you wanted to use this pointer in a developer defined function or method outside of the MainWindow class, you would have to pass the pointer as a reference (or pointer to the pointer).

might have to include a line similar to this in the MainWindow Constructor

painterPointer = new QPainter(this);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM