首页 > 解决方案 > 如何在paintEvent() 之外绘制?Qt, C++

问题描述

我正在尝试在paintEvent() 之外绘制矩形。

如果用户用鼠标单击并拖动屏幕,应用程序应绘制“选择区域”。

但似乎不可能在paintEvent() 之外进行绘画。

我已经用 ReleaseDC() 在 MFC 上解决了这个问题。

这是我在 MFC 上的代码:

void DrawingPaper::DrawSelectingArea() {
    CDC *dc = this->GetDC();
    CPen pen;
    CPen *oldPen;

    dc->SetROP2(R2_NOTXORPEN);

    pen.CreatePen(PS_DOT, 1, RGB(166, 166, 166));

    oldPen = dc->SelectObject(&pen);

    dc->Rectangle(this->startX, this->startY, this->currentX, this->currentY);

    dc->SelectObject(oldPen);
    this->ReleaseDC(dc);

    DeleteObject(pen);
}

尽管代码不在 OnPaint() 中,但它运行良好。

但是在 Qt 上,怎么做?

这是我在 Qt 上的代码:

void DrawingPaper::DrawSelectingArea() {
    QPainter painter(this);

    QRect drawRect(this->startX, this->startY, this->currentX, this->currentY);
    painter.drawRect(drawRect);

    //this->ReleaseDC(dc);
}

它不起作用,因为绘制矩形的画家将被paintEvent()中的其他QPainter删除。

有没有像 ReleaseDC() 这样的解决方案?

我在 Qt 5.12.6 上。

谢谢你的帮助。

标签: c++qtpaint

解决方案


简短的回答是,你不能——Qt 不能那样工作。如果您不在paintEvent() 之外并且想要重新绘制您的小部件,您需要做的是调用update() 来代替。这将导致paintEvent() 被尽快调用,然后您在paintEvent() 中的代码可以进行实际的绘画。

也就是说,如果您绝对必须在其他地方进行绘画,您可以创建一个宽度和高度与您的小部件相同的 QPixmap 对象,并将指向该 QPixmap 的指针传递给 QPainter 对象的构造函数,然后绘画到 QPixmap 中。然后当你完成后,调用update(),这将导致paintEvent()被尽快调用,并且在paintEvent()调用中你可以调用drawPixmap()并将QPixmap作为参数,将像素从QPixmap复制到小部件的屏幕缓冲区。请注意,这比直接在paintEvent() 中直接进行原始绘画效率低,因为这种方法需要额外复制像素(并且可能还会导致图像被绘制得比必要的更频繁)


推荐阅读