1

我在使用 QT 框架时遇到了问题,尤其是paintEvent使用QWidget. 我有一个QWidget设置,并且正在覆盖paintEvent它。我需要渲染一堆 51 x 19 的矩形(网格系统),导致绘制 969 个矩形。这是在 for 循环中完成的。然后我还需要在每个网格上绘制一个图像。被QWidget添加到 aQMainWindow中,如图所示。

这很好用,但是每个打开的窗口都占用了 47% 的 CPU!而且我想让用户像这样打开多个窗口,就像一次打开 3-4 个窗口,这使 CPU 接近 150%。

为什么会这样?这里是paintEvent内容。JNI 调用不会导致 CPU 使用率,将它们注释掉并不会降低它,但注释掉p.fillRectand Renderer::renderString(绘制图像)会将 CPU 降低到大约 5%。

// Background
QPainter p(this);
p.fillRect(0, 0, this->width(), this->height(), QBrush(QColor(0, 0, 0)));

// Lines
for (int y = 0; y < Global::terminalHeight; y++) {
    // Line and color method ID
    jmethodID lineid = Manager::jenv->GetMethodID(this->javaClass, "getLine", "(I)Ljava/lang/String;");
    error();
    jmethodID colorid = Manager::jenv->GetMethodID(this->javaClass, "getColorLine", "(I)Ljava/lang/String;");
    error();

    // Values
    jstring jl = (jstring) Manager::jenv->CallObjectMethod(this->javaObject, lineid, jint(y));
    error();
    jstring cjl = (jstring) Manager::jenv->CallObjectMethod(this->javaObject, colorid, jint(y));
    error();

    // Convert to C values
    const char *l = Manager::jenv->GetStringUTFChars(jl, 0);
    const char *cl = Manager::jenv->GetStringUTFChars(cjl, 0);
    QString line = QString(l);
    QString color = QString(cl);

    // Render line
    for (int x = 0; x < Global::terminalWidth; x++) {
        QColor bg = Renderer::colorForHex(color.mid(x + color.length() / 2, 1));

        // Cell location on widget
        int cellx = x * Global::cellWidth + Global::xoffset;
        int celly = y * Global::cellHeight + Global::yoffset;

        // Background
        p.fillRect(cellx, celly, Global::cellWidth, Global::cellHeight, QBrush(bg));

        // String
        // Renders the image to the grid
        Renderer::renderString(p, tc, text, cellx, celly);
    }

    // Release
    Manager::jenv->ReleaseStringUTFChars(jl, l);
    Manager::jenv->ReleaseStringUTFChars(cjl, cl);
}
4

1 回答 1

0

您遇到的问题是,每次您在 QPainter 上调用绘图函数时,都会为需要绘制的内容设置画家的开销,尤其是当笔和画笔需要更改时。当您调用该函数超过 900 次时,Painter 需要更改其内部属性进行渲染的次数超过 900 次,这将解释为什么注释掉 drawRect 和 drawString 函数会降低 CPU 使用率。

要解决此问题,您需要批量处理所有相同类型的绘制调用,其中一个类型使用相同的画笔和钢笔。为此,您可以使用 QPainterPath 类并使用 addRect(..) 等函数添加所需的对象;确保您在绘制功能之外执行此操作!

例如,如果您要绘制棋盘图案,您将创建两个 QPainterPath 对象并将所有白色方块添加到一个对象,并将所有黑色方块添加到另一个对象。然后在绘图时使用 QPainter 函数 drawPath。这只需要两次调用来绘制整个电路板。

当然,如果您需要每个正方形都具有不同的颜色,那么您仍然会遇到同样的问题,在这种情况下,我建议您生成您需要的图像并进行渲染。

于 2013-07-03T12:29:53.470 回答