ペインターをクラス変数に入れることはできますか? :
protected:
QPainter *myPainter;
...
void MyWidget::paintEvent(QPaintEvent *event)
{
myPainter = new QPainter(this);
ペインターをクラス変数に入れることはできますか? :
protected:
QPainter *myPainter;
...
void MyWidget::paintEvent(QPaintEvent *event)
{
myPainter = new QPainter(this);
より具体的に再入可能性に対処するための新しい anser...
danatelはこのメッセージに次のコメントを残しました(一部):
再入可能とは、この特定の状況を意味します。1) paintEvent ハンドラーが QPainter をクラス変数に保存します。2) paintEvent ハンドラがサブルーチンを呼び出して何かを描画する 3) サブルーチンの 1 つが Qt メソッドを呼び出す 4) この Qt メソッドが別の paintEvent を再帰的に生成する
これに対する答えは、本当に奇妙なことをしない限り、おそらく受け入れられるはずだということです。(そして、奇妙なことをすると、Qt はおそらく警告するか、中止します。) 再入可能とはどういう意味かについて、まだ混乱があるかもしれませんが、paintEvent を生成しても、現在のアクションの実行フローがすぐに停止することはありません。そのイベントを処理します。代わりに (すべてのイベントと同様)、後で処理するためにキューに入れられます。マルチスレッドや processEvents の呼び出しを行っていない限り、独自の関数の 1 つにいるときのコードの実行順序は非常に簡単です。
例として、あなたの手順に従って、より詳細に調べてみましょう。
Foo::paintEvent()
handler は QPainter を作成し、それに設定
Foo::m_painter_p
します。Foo::paintEvent()
を呼び出します
Foo::paintAntarticaFlag()
。Foo::paintAntarticaFlag()
: a) を使用しFoo::m_painter_p
、次に b) を呼び出す何かを呼び出しFoo::update()
、次に c) をさらに使用しFoo::m_painter_p
ます。Foo::update()
は実際には Qt メソッドであり、Foo の paintEvent を生成します。update はeventを作成するため、上記のシーケンスは問題ありません。これは処理の遅延を意味します。代わりに Foo::repaint() を呼び出すと、即座に Foo::paintEvent() への再帰が発生し、同じオブジェクトに対して複数のペインターを作成しているために Qt が中止されるか、プログラムが中止されます。最終的に (数百ミリ秒で) スタックを吹き飛ばしたからです。
複数のスレッドを実行していて、再描画をトリガーしたいだけの場合でも、他のスレッドからそれを実行できます。これは、適切なタイミングで適切なスレッドによって処理されるように paintEvent をキューに入れるだけだからです。複数のスレッドを実行していて、同じペインターを使用してこれらのフラグを描画したい場合は、そうしないでください。ただしないでください。その場合、各フラグを共有画像に描画し、現在 QPainter を使用している場所にその画像を描画することを検討してください。
それをしないでください。スタックに置くだけで、デストラクタで破棄されたときに自動的に描画が実行されます。
void MyWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// use painter
...
// paint object automatically closes and paint on desctruction
}
ペインターウィジェットを多数のサブルーチン呼び出しに渡さないようにする場合は、クラス変数としてペインターへのポインタを使用することで解決できる可能性があります。前述のように、paintEvent関数で作成/破棄する必要があります。個人的には、おそらくヘルパー関数に渡すだけですが、この方法で行うこともできます。
また、あなたの質問がリエントラントにどのように関連しているかはわかりません。複数のスレッドがある場合、UI要素のすべての描画はUIスレッドにのみ行う必要があります。別のスレッドの画像にペインターを作成することもできますが、その場合は、複数のスレッドではなく、そのスレッドでのみその画像をペイントする必要があります。いずれにせよ、これらの条件を維持している限り、ペインターに呼び出すQt関数の再入可能性の問題に遭遇することはないと思います。