我有一个Windows / Linux Qt 4.3应用程序,它在QTreeView中使用拖放功能。我有两个非常相似的应用程序,它们使用相同的Qt库集。拖放在Linux上都有效,但在Windows上只有一个。
在不起作用的应用程序中,移动鼠标后立即删除QDrag对象。它被事件队列中的DeferredDelete事件删除,该事件在拖动期间仍在Qt中处理。我不知道如何看到导致QDrag对象过早删除的原因。
我无法找到调试此问题的好方法。我已经比较了源代码并且找不到任何明显的东西。我尝试使用其他应用程序中的一个应用程序的代码。
有什么建议吗?
更新
QDrag操作失败的原因是因为COM未成功初始化,因此在QDrag :: exec中对DoDragDrop的调用立即返回。 QApplication尝试通过在qt_init中调用OleInitialize来初始化COM,但它失败并显示错误“设置后无法更改线程模式”。
有趣的是,即使OleInitialize是在main中完成的第一件事情,也会发生这种情况,因此线程模式最初是由某些外部依赖项设置的。在Windows上运行的应用程序之间的区别之一是失败的应用程序也包含.NET代码,因此可能是问题。
解决:
此问题是COM / CLR互操作问题。 CLR在初始化时将公寓状态设置为MTA,然后当Qt尝试初始化COM时它失败。 Adam Nathan在Gotcha with STAThreadAttribute and Managed C++中讨论了此问题和旧解决方案。在Visual Studio 2005中,您可以在配置属性>中设置/ CLRTHREADATTRIBUTE:STA编译器选项。链接器>高级可将线程属性设置为STA,而无需创建新的入口点。
答案 0 :(得分:1)
我不知道是什么导致这种情况,但我会尝试通过子类化QDrag来找出,覆盖deleteLater()(好吧,重新实现它,但因为它是一个插槽,无论如何都会被调用),使用它代替一个QDrag并在deleteLater()中放置一个断点。