Qt:在 class 中有一个 QPainter 对象实例
Qt : Having a single instance of QPainter object in a class
我在 Qt
做一个项目,有一个对象 QPainter
声明为:
QPainter painter(this);
这里指的是现在class。我的问题是我需要声明此对象,以便整个 class 函数都可以访问它。
如果我在构造函数中声明它,那么它的范围对其他函数无效,并且我不能在我的 .cpp
文件中的所有函数之外声明,因为 this
变量没有任何意义.
那么我如何声明我的对象以便所有函数都可以访问它?
编辑:画家代码:
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);
}
}
鼠标事件代码:
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();
}
}
}
问题: 我想创建点,但我不希望它从小部件 (mainWindow) 中消失。在这里,因为对象是在 paintEvent 方法期间创建的,每次我正在绘制的点在绘制下一个点时消失。
如果我在 paintEvent 之外声明它,则会出现以下错误:
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
这就是 class 属性 的用途:
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_;
}
一般来说,声明 QPainter object globally is not a good idea. It is better to construct it in the QWidget::paintEvent(它将在何处激活),并且正如@Mat 所说,将其(通过引用)传递给需要它的函数。
在您的特定情况下,点消失是因为重新绘制了小部件,而不是因为 QPainter 被销毁了。因此,策略应该是创建和管理点缓冲区。在鼠标事件中向缓冲区添加一个点,例如QWidget::mousePressEvent(也有一些管理,例如限制点数)并在绘制事件中 - 从缓冲区绘制所有点。
这是一个过于简单的示例,可以很容易地针对您的特定目的进行调整:
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); }
}
在 mainWindow.h 中 window class 的私有访问说明符中,您可以写下这行
QPainter *painterPointer
创建一个可在所有 MainWindow 槽中访问的指针。您可以使用那个 painterPointer,就好像它是在任何槽中初始化的任何画家指针一样。但是,如果您想在 MainWindow class 之外的开发人员定义的函数或方法中使用此指针,则必须将指针作为引用(或指向指针的指针)传递。
可能必须在 MainWindow 构造函数中包含与此类似的行
painterPointer = new QPainter(this);
我在 Qt
做一个项目,有一个对象 QPainter
声明为:
QPainter painter(this);
这里指的是现在class。我的问题是我需要声明此对象,以便整个 class 函数都可以访问它。
如果我在构造函数中声明它,那么它的范围对其他函数无效,并且我不能在我的 .cpp
文件中的所有函数之外声明,因为 this
变量没有任何意义.
那么我如何声明我的对象以便所有函数都可以访问它?
编辑:画家代码:
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);
}
}
鼠标事件代码:
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();
}
}
}
问题: 我想创建点,但我不希望它从小部件 (mainWindow) 中消失。在这里,因为对象是在 paintEvent 方法期间创建的,每次我正在绘制的点在绘制下一个点时消失。
如果我在 paintEvent 之外声明它,则会出现以下错误:
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
这就是 class 属性 的用途:
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_;
}
一般来说,声明 QPainter object globally is not a good idea. It is better to construct it in the QWidget::paintEvent(它将在何处激活),并且正如@Mat 所说,将其(通过引用)传递给需要它的函数。
在您的特定情况下,点消失是因为重新绘制了小部件,而不是因为 QPainter 被销毁了。因此,策略应该是创建和管理点缓冲区。在鼠标事件中向缓冲区添加一个点,例如QWidget::mousePressEvent(也有一些管理,例如限制点数)并在绘制事件中 - 从缓冲区绘制所有点。
这是一个过于简单的示例,可以很容易地针对您的特定目的进行调整:
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); }
}
在 mainWindow.h 中 window class 的私有访问说明符中,您可以写下这行
QPainter *painterPointer
创建一个可在所有 MainWindow 槽中访问的指针。您可以使用那个 painterPointer,就好像它是在任何槽中初始化的任何画家指针一样。但是,如果您想在 MainWindow class 之外的开发人员定义的函数或方法中使用此指针,则必须将指针作为引用(或指向指针的指针)传递。
可能必须在 MainWindow 构造函数中包含与此类似的行
painterPointer = new QPainter(this);