2008-09-19 226 views
4

我有一個使用QTreeView拖放的Windows/Linux Qt 4.3應用程序。我有兩個使用相同的Qt庫的非常相似的應用程序。在Linux上拖放作品,但只在Windows上拖放作品。QDrag在拖拽時被破壞

在不起作用的應用程序中,只要移動鼠標,QDrag對象就會被刪除。它由拖動過程中仍然在Qt中處理的事件隊列中的DeferredDelete事件刪除。我不知道如何查看導致QDrag對象過早被刪除的原因。

我找不出一個很好的方法來調試這個問題。我比較了來源,找不到任何明顯的東西。我曾嘗試使用其他應用程序中某個應用程序的代碼。

有什麼建議嗎?

更新:

之所以失敗QDrag操作,因爲COM未成功初始化,因此呼叫在QDrag的DoDragDrop :: EXEC立即返回。 QApplication試圖通過在qt_init中調用OleInitialize來初始化COM,但是它失敗了,出現錯誤「設置後無法更改線程模式」。

有趣的是,即使在OleInitialize是在main中完成的第一件事情時,也會發生這種情況,所以線程模式最初由某個外部依賴項設置。在Windows上工作的應用程序之間的差異之一是,失敗的應用程序也包含.NET代碼,所以也許這就是問題所在。

解決:

這個問題是一個COM/CLR互操作問題。 CLR在初始化時將公寓狀態設置爲MTA,然後在Qt嘗試初始化COM時失敗。 Adam NathanGotcha with STAThreadAttribute and Managed C++中討論了此問題和舊解決方案。在Visual Studio 2005中,您可以在配置屬性>鏈接器>高級中設置/ CLRTHREADATTRIBUTE:STA編譯器選項,以將線程屬性設置爲STA,而無需創建新入口點。

+0

望着的Qt 4.3文檔瞭解QDrag :: EXEC在 http://doc.trolltech.com/4.3/qdrag.html >在Windows上,Qt的事件循環是 >受阻,而在操作。 所以在我看來,這不應該發生... 對不起,我知道這可能沒有多大幫助。 – 2008-09-20 11:33:11

回答

1

我不知道是什麼會導致這種情況,但我會試圖通過繼承QDrag,覆蓋deleteLater()(好吧,重新實現它,但因爲它是一個插槽,它會被調用)一個QDrag並在deleteLater()中放置一個斷點。