web-dev-qa-db-ja.com

QT再描画/再描画/更新/何かをする

私はQTが初めてです。ディスプレイを強制的に更新できることは理解していますが、その方法を理解しようとして髪の毛をすべて引き出しました。これが私が具体的にやろうとしていることです。

ボタン(onClickシグナルイベント)を押します。このボタンは、ディスプレイ上の画像(QLabel)を変更するコードを実行し、入力を待機してから、新しい画像(異なるQLabel)を変更することで続行します。すべてを試してみましたが、onclickシグナルイベントコードが完了するまで表示は更新されません。現在、ユーザーの入力を待っていません。テスト目的でusleep(〜500 ms)を使用しています。

私が読んだことから、QTはイベント駆動型です。つまり、基本的に一連のイベントを作成し、キューに入れて、(onClick signalイベント)が(メインループ)/(イベントハンドラ)に戻るときに実行されます。関数が完了するまで待ちたくありません。イベントに完全に基づいてこのルーチンを実行しなければならない場合、プログラミングが非常に苦痛になります。

QLabel pixmapを強制的に更新するにはどうすればよいですか。私はすべてを試しました。以下は、onClickシグナルイベントハンドラーで試したすべてのコードです。 (upButtonはピックスマップであるQLabelの名前です)

update();
repaint();
ui->upButton->setUpdatesEnabled(TRUE);
update();
repaint();
QPaintEvent paintevent(ui->upButton->childrenRegion());
QPaintEvent * test = &paintevent;
paintEvent(test);
this->changeEvent(test);
ui->upButton->update();
ui->upButton->repaint();
ui->upButton->repaint(ui->upButton->childrenRegion());
repaint();
QApplication::sendPostedEvents();
this->parentWidget()->update();
usleep(100000);

ご覧のとおり、私はこの時点で暗闇で撮影しています。サンプルコードを見て、すべての宿題をしようとしましたが、迷子になりました。ヘルプ、アドバイス、サンプルコードを評価してください。

21
Jason Kotzin

私は、コンピューターが何かが起こるのを待っている短い時間をエミュレートするためにスリープを使用していました。

私の質問で述べたように、イベントを使用したくありませんでした。イベントを非常に簡単に達成するのは非常に多くの不必要な作業だからです。

また、プログラムを続行するために発生する必要がある「イベント」はUSBイベントです。私はHIDクラスのデバイスを使用しているため、待機ループなしでイベントが発生するように設定する方法はありません。 USB HIDクラスは割り込みの設定を許可しません、OSはデバイスを要求します。

私は上記を機能させることができました。デバッガーを調べてみると、スリープ機能の前に表示が更新されることに気付きました。プログラムを個別に実行すると、画面が1%更新されるというランダムな結果が得られました。スリープ機能を取り除き、その場所に遅延をエミュレートする他のコードをいくつか追加しましたが、問題ありませんでした。

誰でも知っているように、これは可能であり、禁じられているわけではなく、次のように簡単に実行できます。

qApp->processEvents();

qAppはQApplicationヘッダーのグローバル外部変数です。

このUSBイベントはフローをトリッキーにするため、QWaitConditionクラスを見つけました。 USBイベントを待つプロセスを開始するつもりでした。プロセスがルーチンを続行するための待機条件を解放するまで待機します。

しかし、これが悪い考えだと思う人がいたら、声をかけてください。 PiedPiperとHostile Forkからのフィードバックに本当に感謝しています。

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

22
Jason Kotzin

イベントハンドラでの入力を待つべきではありません。イベントを意図したとおりに使用するには、プログラムのロジックを再考する必要があります。イベントループに戻る場合、コード内のupdate()およびrepaint()呼び出しはすべて不要です。

7
PiedPiper

複数のレイヤー化されたウィジェット、またはウィジェット内にウィジェットがある場合、repaint()イベントを呼び出すと役立つことがあります。

例えば

this->repaint();
this->parentWidget()->repaint();
this->parentWidget()->parentWidget()->repaint();

これは、処理を別のスレッドにプッシュしたり、追加のイベントハンドラーを作成したりするよりもはるかに簡単です。

5
Goddard

私が正しく理解していれば、スロットがあり、このスロットにQLabelに表示される画像を更新します。ただし、スロットが終了する前にこの変更を表示する必要があります。

その場合は、update()イベントを発行し、qApp-> processEvents()を呼び出します。このメソッドは、イベントキューで待機しているイベントを処理してから戻ります。そのため、これが後の処理になる可能性があります。

PS:update()はまったく必要ないかもしれませんが、よくわかりません。

2
erelender