Russian Qt Forum
Ноябрь 01, 2024, 03:09 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Drag and Drop: удаление QDrag  (Прочитано 4757 раз)
Alp
Гость
« : Декабрь 21, 2009, 21:00 »

Есть следующая ситуация: сложный вложенный виджет (7 уровней вложенности), с одного из его детей начинается Drag. Вся обвеска для драг-дропа вынесена в отдельный класс QDraggableItem с конструктором принимающим виджет (для инициализации QDrag требуется виджет, с которого драг начался).
По завершению перетаскивания, в dropEvent'е происходит проверка стартового виджета и если с него был вытащен последний виджет стартовый удаляется.

И вот тут приложение падает поскольку владельцем QDrag'а был тот самый стартовый виджет. Если убираю удаление виджета QDrag успешно разрушается, но в непонятный момент. Создавать QDrag с родителем 0х0 (с целью самостоятельно разрушить, когда он уже не нужен) нельзя - драг не начнется. Удалять созданный драг руками так же не получается.

Вопрос: как эту ситуацию можно разрешить?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Декабрь 21, 2009, 21:30 »

Сам не решал но делал бы так: в деструкторе перекрытого QDrag испустил бы сигнал созданный с QueuedConnection (т.е. через очередь) а в слоте для этого сигнала уже спокойно удалял источник или что надо

Edit: и перекрывать не надо, есть удобный готовый сигнал destroyed
« Последнее редактирование: Декабрь 21, 2009, 23:44 от Igors » Записан
BRE
Гость
« Ответ #2 : Декабрь 21, 2009, 23:08 »

Попробуй удалять с помощью deleteLater.
Записан
Alp
Гость
« Ответ #3 : Декабрь 22, 2009, 01:13 »

Сам не решал но делал бы так: в деструкторе перекрытого QDrag испустил бы сигнал созданный с QueuedConnection (т.е. через очередь) а в слоте для этого сигнала уже спокойно удалял источник или что надо

Edit: и перекрывать не надо, есть удобный готовый сигнал destroyed
Спасибо, почитал про этот сигнал. Если я верно понял мысль, то мне надо вешаться на QDrag::destroyed, так? Увы, сделать не получится вот почему: обвязка для драга вынесена, как я писал в отдельный класс, который не наследует QObject и не декларирует Q_OBJECT, т.е. про сигналы-слоты он не знает ничего, но зато умеет создавать QDrag, запоминать точку начала перетаскивания и принимать или не принимать dragEnter.

Вот такая декларация:
Код
C++ (Qt)
class DraggableItem
{
   QWidget* widgetSelf;
 
   bool draggable;
   bool dragging;
   QPoint dragPos;
 
   QString     mimeType;
   QByteArray  mimeData;
 
protected:
   QPixmap dragpix;
   virtual void SetDragPixmap();
 
public:
   DraggableItem(QWidget* widgetSelf);
   virtual ~DraggableItem()    {}
 
   void SetDraggable(bool d)   { draggable = d; }
 
   bool Draggable()            { return draggable; }
 
   bool Dragging()             { return dragging; }
 
   QPoint DragPos()            { return dragPos; }
 
   void SetMimeData(const std::string& type, const QByteArray& data = QByteArray());
 
protected /*slots*/:
   virtual void mouseMoveEvent(QMouseEvent*);
   virtual void mousePressEvent(QMouseEvent*);
 
   virtual void dragEnterEvent(QDragEnterEvent*);
   virtual void dragLeaveEvent(QDragLeaveEvent*);
   virtual void dropEvent(QDropEvent*);
 
protected:
   virtual void StartDrag();
};
 

Т.е. имитация методов QWidget'а, реализующие базовую функциональность и перегружаемые в потомках.
На такое извращение пришлось пойти по той причине, что множественное наследование QObject не допускается, а делать линейное наследование просто глупо (например класс QEditLabel наследует: QBaseExtLabel(отсюда тянется QObject), EditableItem, DraggableItem, PairItem<QEditLabel>, в них заключена голая функциональность).

Привеситься на QDrag::destroyed с привязкой его к widgetSelf я не могу за отсутствием общего предка у удаляемых виджетов.
Записан
Alp
Гость
« Ответ #4 : Декабрь 22, 2009, 01:15 »

Попробуй удалять с помощью deleteLater.
Не будет ли в этом случае UI отображать "как бы" удаленный виджет, который "пока не успел удалиться потому, что QDrag все еще жив"? Отсюда мой вопрос и проистекает - не удалось вяснить когда же именно происходит удаление QDrag'а его "источником".
Записан
BRE
Гость
« Ответ #5 : Декабрь 22, 2009, 09:17 »

Не будет ли в этом случае UI отображать "как бы" удаленный виджет, который "пока не успел удалиться потому, что QDrag все еще жив"? Отсюда мой вопрос и проистекает - не удалось вяснить когда же именно происходит удаление QDrag'а его "источником".
Что значит не удалось выяснить? В документации все написано + есть исходники + можно проверить самому.  Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Декабрь 22, 2009, 16:56 »

Спасибо, почитал про этот сигнал. Если я верно понял мысль, то мне надо вешаться на QDrag::destroyed, так? Увы, сделать не получится вот почему: обвязка для драга вынесена, как я писал в отдельный класс, который не наследует QObject и не декларирует Q_OBJECT, т.е. про сигналы-слоты он не знает ничего, но зато умеет создавать QDrag, запоминать точку начала перетаскивания и принимать или не принимать dragEnter.
...
Привеситься на QDrag::destroyed с привязкой его к widgetSelf я не могу за отсутствием общего предка у удаляемых виджетов.
Не проходят сигналы - не беда, никто не мешает Вам послать postEvent в деструкторе.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.131 секунд. Запросов: 23.