4

QTreeView でドラッグ アンド ドロップを使用する Windows/Linux Qt 4.3 アプリケーションがあります。同じ Qt ライブラリ セットを使用する 2 つの非常によく似たアプリケーションがあります。ドラッグ アンド ドロップは、Linux では両方で機能しますが、Windows では 1 つのみで機能します。

動作しないアプリケーションでは、マウスを動かすとすぐに QDrag オブジェクトが削除されます。これは、ドラッグ中に Qt でまだ処理されているイベント キューから DeferredDelete イベントによって削除されます。QDrag オブジェクトが途中で削除される原因を確認する方法がわかりません。

この問題をデバッグする良い方法がわかりません。ソースを比較しましたが、明らかなものは見つかりません。あるアプリケーションのコードを別のアプリケーションで使用しようとしました。

助言がありますか?

アップデート:

QDrag 操作が失敗した理由は、COM が正常に初期化されなかったため、QDrag::exec の DoDragDrop への呼び出しがすぐに返されたためです。QApplication は、qt_init で OleInitialize を呼び出して COM を初期化しようとしましたが、「設定後にスレッド モードを変更できません」というエラーで失敗しました。

興味深いことに、OleInitialize が main で最初に実行される場合でもこれが発生するため、スレッド モードは外部依存関係によって最初に設定されます。Windows で動作するアプリケーションの違いの 1 つは、失敗するアプリケーションには .NET コードも含まれているため、それが問題である可能性があります。

解決済み:

この問題は、COM/CLR 相互運用の問題です。CLR は、初期化時にアパートメント状態を MTA に設定し、Qt が COM を初期化しようとすると失敗します。この問題と古い解決策については、Adam NathanGotcha で STAThreadAttribute と Managed C++について説明しています。Visual Studio 2005 では、[構成プロパティ] > [リンカー] > [詳細設定] で /CLRTHREADATTRIBUTE:STA コンパイラ オプションを設定して、新しいエントリ ポイントを作成しなくても、スレッド属性を STA に設定できます。

4

1 に答える 1

1

何が原因なのかわかりませんが、QDrag をサブクラス化し、deleteLater() を上書きして (まあ、再実装しますが、スロットなのでとにかく呼び出されます)、QDrag の代わりにこれを使用し、 deleteLater() にブレークポイントを設定します。

于 2008-09-20T12:24:37.723 に答える