1

QT フレームワーク、特にpaintEventof の使用に問題がありQWidgetます。QWidgetセットアップがあり、それをオーバーライドしpaintEventています。51 x 19 の一連の四角形 (グリッド システム) をレンダリングする必要があり、969 個の四角形が描画されます。これは for ループで行われます。次に、これらのグリッドのそれぞれに画像を描画する必要もあります。QWidgetが に追加され、表示QMainWindowされます。

これはうまく機能しますが、開いているウィンドウごとに 47% の CPU を使用しています! そして、ユーザーがこのように複数のウィンドウを開くことができるようにしたいと考えています。一度に 3 ~ 4 個のウィンドウを開くと、CPU が 150% 近くになります。

なぜこれが起こるのですか?内容はこちらpaintEvent。JNI 呼び出しは CPU 使用率を引き起こしません。コメント アウトしても CPU 使用率は低下しませんが、(画像を描画する) p.fillRectand をコメント アウトすると、CPU 使用率Renderer::renderStringは約 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(..); などの関数で追加します。ペイント機能の外でこれを行うようにしてください!

たとえば、チェス盤のパターンを描画する場合は、2 つの QPainterPath オブジェクトを作成し、すべての白い正方形を 1 つに追加し、すべての黒い正方形を別のオブジェクトに追加します。次に、描画に関しては、QPainter 関数 drawPath を使用します。これにより、ボード全体を描画するために必要な呼び出しは 2 回だけです。

もちろん、各正方形を異なる色にする必要がある場合でも、同じ問題が発生する可能性があります。その場合は、必要な画像を生成し、代わりにレンダリングすることをお勧めします。

于 2013-07-03T12:29:53.470 に答える