У меня есть приложение Windows/Linux Qt 4.3, которое использует перетаскивание в QTreeView. У меня есть два очень похожих приложения, которые используют один и тот же набор библиотек Qt. Перетаскивание работает как в Linux, так и только в Windows.
В приложении, которое не работает, объект QDrag удаляется при перемещении мыши. Он удаляется событием DeferredDelete из очереди событий, которая все еще обрабатывается в Qt во время перетаскивания. Я не знаю, как увидеть, что вызывает преждевременное удаление объекта QDrag.
Я не могу найти хороший способ отладки этой проблемы. Я сравнил источник и не нашел ничего очевидного. Я попытался использовать код из одного из приложений в другом приложении.
Какие-либо предложения?
Обновление:
Причина сбоя операции QDrag заключается в том, что COM не был успешно инициализирован, поэтому вызов DoDragDrop в QDrag::exec возвращается немедленно. QApplication попытался инициализировать COM, вызвав OleInitialize в qt_init, но это не удалось с ошибкой «Невозможно изменить режим потока после его установки».
Интересно то, что это происходит даже тогда, когда OleInitialize является первым, что делается в main, поэтому режим потока изначально устанавливается какой-то внешней зависимостью. Одно из различий между приложениями, которые работают в Windows, заключается в том, что приложение, которое дает сбой, также содержит код .NET, поэтому, возможно, проблема в нем.
Решено:
Эта проблема связана с взаимодействием COM/CLR. CLR устанавливает состояние подразделения в MTA при инициализации, а затем, когда Qt пытается инициализировать COM, происходит сбой. Эта проблема и старое решение обсуждаются Адамом Натаном в Попался с STAThreadAttribute и Managed C++. В Visual Studio 2005 можно задать параметр компилятора /CLRTHREADATTRIBUTE:STA в разделе Свойства конфигурации > Компоновщик > Дополнительно, чтобы установить для атрибута потоков значение STA без необходимости создания новой точки входа.