我有一个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,而无需创建新的入口点。
最佳答案
我不知道是什么原因造成的,但是我会尝试通过子类化QDrag来发现,覆盖deleteLater()(嗯,重新实现它,但是由于它是一个插槽,无论如何都会被调用),使用它代替QDrag并在deleteLater()中放置一个断点。