0

ClassQt にGUI C++がSLOTあり、テキスト ボックスとラベルの配列を に追加しますQGridLayout。配列は、変数 say に応じて正方nです。つまり、n == 1010x10 QTextbox&QLabelがある場合QGridLayout。基本的に、ユーザーが [増加] ボタンを押すと、 の値がn1 増加し、それに応じてQTextbox&QLabelが作成され、SLOT& に追加されますQGridLayout。の値が の場合n、GUI が更新されるまでに1 ~ 215かかります。ただし、その中で使用すると、実際の実行時間は約100 msであることがわかりました。にいる間 QTimeSLOTSLOT デバッグモードでQDebugは、GUI がより高い値のn. なぜそれほどの遅延が発生するのかを知りたいのですが、その後に何が実行されているのかを知りたいSLOTので、同じ時間を測定することができます。私は自分自身を明確にしたことを願っています。私の質問を理解できなかった場合はお知らせください。ありがとうございました。

実際、正確なコードは今手元にありません。そこで、コードのロジックを強調するサンプル コードを作成しました。できるだけ早く準備したので、構文エラーは無視してください。申し訳ありません:(コードスニペットは次のとおりです。

Class A
{
private:
    int n;
    QList <QLabel *> *labelList;
    QList <QTextEdit *> *textList;
    QGridLayout *inp;

    public slots:
        updateGUI();
}

A::updateGUI()
{
    QTime t;
    t.start();

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
                            int even = j%2;
            QLabel *tempLab = new QLabel();
            //some stuff for initialisation of the QLabel
            QTextEdit *tempText = new QTextEdit();
            //some stuff for initialisation of the QTextEdit
            labelList->append(tempLab);
            textList->append(tempText);
                            if(even == 0)
                inp->AddWidget(tempLab, i, j, 5, 5, Qt::AlignCenter);
            else
                                inp->AddWidget(tempText, i, j, 5, 5, Qt::AlignCenter);
        }
    }

    QDebug("%d", t.elapsed());
}

PS:QTime tobj.start()は 1 行目SLOT&QDebug("%d", tobj.elapsed())SLOTOfcourse!の最後の行です。

4

3 に答える 3

2

ウィジェットで一括更新を行う場合は、updatesEnabled プロパティをオフにします。これにより、(11*11-10*10) 個の新しいボタンを追加するときに、21 個の個別の更新が防止されます。

于 2013-02-13T12:02:59.960 に答える
1

0.1 秒の遅延は、大量のウィジェットを作成してからグリッドに追加しているためです (明らかにオーバーヘッドがあるウィジェットを追加するたびに、他のセルの寸法を「シャッフル」ラウンドとして更新する必要があります)。 )。

では、なぜタイマーの後にさらに遅れるのでしょうか? スロットによって生成されたすべてのペイントおよびサイズ変更イベントは、スロットの実行中に停止されたイベント キューに入れられました。スロットが完了したら、これらすべてのタスクを処理する必要があります。

他の人が言ったことに加えて、あなたがしていることには 2 つの根本的な欠陥があります。

  • 既存のウィジェットをすべて削除して、場合によっては単一のウィジェットを追加します。これがどれほどひどく非効率的であるかを説明する必要はないと思いました...
  • グリッド内の何百ものテキスト ボックスとラベルがユーザーに表示される状況に陥った場合、UI は失敗しています。 ユーザーがこのすべてのデータを操作できるようにするためのより良い方法を考え出す必要があります。
于 2013-02-13T14:43:32.420 に答える
1

同じ問題のコードを投稿すると、本当に役に立ちます。n=10 を選択してから n=7 を選択すると、スロットはどのように反応しますか? レイアウトから最後の 3 つの項目を削除しますか? また、n=7 を選択してから n=10 を選択すると、最後の 3 行だけを追加しようとしますか? レイアウトからアイテムを削除せず、既存のアイテムに新しいアイテムを追加しようとしている可能性はありますか?

そうである場合は、次の方法でレイアウトからすべてのウィジェットを削除できます。

QLayoutItem* item;
while ( ( item = %your_layout_name%->takeAt( 0 ) ) != NULL ){
    delete item->widget();
}
delete item;

または、ウィジェットのオブジェクト名 (または QList QVector などに格納されているハンドル) でウィジェットを削除できます。

swLayout->removeWidget(myTextEdit);

UPD: コードがいくつかあるので、labelList と textList もクリアする必要があります。次に、行

inp->AddWidget(tempLab, i, j, 5, 5, Qt::AlignCenter);
inp->AddWidget(tempText, i, j, 5, 5, Qt::AlignCenter);

高さと幅が 5 の位置 (i,j) のレイアウト inp に tempLab ウィジェットを追加しようとした後、同じ場所に別のウィジェット tempText を追加しようとしましたが、これは明らかに間違っています。

次に、ループ自体が正しくありません。

for(int i = 0; i < n; i++)
{
    for(int j = 0; j < n; j++)
    {

このようなループを作成する場合は、次のようにウィジェットを追加します:

inp->AddWidget(tempLab, i, 0, 5, 5, Qt::AlignCenter);
inp->AddWidget(tempLab, i, 1, 5, 5, Qt::AlignCenter);
inp->AddWidget(tempLab, i, n, 5, 5, Qt::AlignCenter);

ただし、ウィジェットの幅と高さを 5 に設定しているため、別の方法でウィジェットを追加する必要があります。そうしないと、ウィジェットが互いに塗りつぶされてしまいます。

inp->AddWidget(tempText, i*5, j*5, 5, 5, Qt::AlignCenter);
于 2013-02-13T12:02:49.843 に答える