QDrag уничтожается при перетаскивании - PullRequest
4 голосов
/ 20 сентября 2008

У меня есть приложение для 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 в Свойства конфигурации> Linker> Advanced , чтобы установить атрибут потока в STA без необходимости создания новой точки входа.

1 Ответ

1 голос
/ 20 сентября 2008

Я понятия не имею, что может быть причиной этого, но я бы попытался выяснить это путем подкласса QDrag, перезаписать deleteLater () (ну, переопределить его, но, поскольку это слот, он все равно будет вызываться), используйте это вместо QDrag и поставить точку останова в deleteLater ().

...