2

必要以上の詳細を記載して申し訳ありません。Canvas次のようなクラスがあります。

class Canvas : public QWidget
{
    Q_OBJECT
public:
    explicit Canvas(int width = 700, int height = 700, QWidget *parent = 0);
    void setDelegate(CanvasDelegate *delegate);
private:
    CanvasDelegate *delegate;
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *resizeEvent);
    [...]
};

Canvas::paintEvent(QPaintEvent *)関数は次のように実装されます。

void Canvas::paintEvent(QPaintEvent *)
{
    delegate->redrawBuffer();
    QPainter canvas_painter(this);
    canvas_painter.drawImage(0, 0, *(delegate->getImage()));
}

したがって、クラスCanvasDelegateは次のようになります。

class CanvasDelegate
{
    friend class Canvas;

public:
    CanvasDelegate(const Canvas *canvas);
    ~CanvasDelegate();

    const QImage * getImage() const;

    void drawPoint(const Complex &z, const QColor &color = "black", int width = 3);
    [...]
    virtual void redrawBuffer(const H2Isometry &mobius = H2Isometry::identity()) = 0;
    virtual void mousePress(QMouseEvent * mouseEvent) = 0;
    [...]


protected:
    const Canvas *canvas;

    int sizeX, sizeY;
    [...]

    QPen *pen;
    QImage *image;
    QPainter *painter;

    void rescale(int sizeX, int sizeY);
};

CanvasDelegate のコンストラクタは次のとおりです。

CanvasDelegate::CanvasDelegate(const Canvas *canvas) : canvas(canvas)
{
    pen = new QPen;
    image = new QImage(canvas->width(), canvas->height(), QImage::Format_RGB32);
    painter = new QPainter(image);
    [...]
}

これがこれまでで最高のデザインかどうかはわかりませんが、これは私の質問ではありません (ただし、コメントは大歓迎です)。Canvas私の問題は、ウィンドウ ( ) のサイズが変更されたときに何が起こるかです。私のコードは次のようになります。

void Canvas::resizeEvent(QResizeEvent *resizeEvent)
{
    QSize newSize = resizeEvent->size();
    delegate->rescale(newSize.width(), newSize.height());
    //update();
}


void CanvasDelegate::rescale(int sizeX, int sizeY)
{
    *image = QImage(sizeX, sizeY, QImage::Format_RGB32);
    painter->eraseRect(0, 0, sizeX, sizeY);

    this->sizeX = sizeX;
    this->sizeY = sizeY;
    [...]
}

問題は、プログラムを実行するとクラッシュすることです。painter->eraseRect(0, 0, sizeX, sizeY);で が呼び出されたときにセグメンテーション違反が発生しているようvoid CanvasDelegate::rescale(int sizeX, int sizeY)です。理由がわかりません。問題が何であるかわかりません。

以前のバージョンでは、次のように記述していました (必要以上に複雑に思えます)。

void CanvasDelegate::rescale(int sizeX, int sizeY)
{
    QImage * oldImage = image;
    QImage * newImage = new QImage(sizeX, sizeY, QImage::Format_RGB32);

    QPainter * oldPainter = painter;
    QPainter * newPainter = new QPainter(newImage);
    newPainter->eraseRect(0, 0, sizeX, sizeY);
    newPainter->setPen(*pen);

    image = newImage;
    painter = newPainter;

    delete oldImage;
    delete oldPainter;

    this->sizeX = sizeX;
    this->sizeY = sizeY;
    [...]
}

しかし、それは機能しません: Qt エラーQPaintDevice: Cannot destroy paint device that is being Paint が発生します。と を削除するdelete oldImage;delete oldPainter;、すべて正常に動作しますが、それは嫌なメモリ リークですよね。

私が書いたことが機能しない理由と、私が何をする必要があるかを誰かが理解していますか?

ご清聴ありがとうございました。

4

1 に答える 1