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

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

Страниц: 1 2 [3] 4   Вниз
  Печать  
Автор Тема: Реализация Undo/Redo действий пользователя в случае mdi интерфейса  (Прочитано 25789 раз)
nata267
Гость
« Ответ #30 : Июнь 20, 2012, 08:45 »

Вот нашла интересный момент. Вот метод, который удаляет выбранные на форме виджеты:

Код:
void FormWindowBase::deleteWidgetList(const QWidgetList &widget_list)
{
    // We need a macro here even for single widgets because the some components (for example,
    // the signal slot editor are connected to widgetRemoved() and add their
    // own commands (for example, to delete w's connections)
    const QString description = widget_list.size() == 1 ?
        tr("Delete '%1'").arg(widget_list.front()->objectName()) : tr("Delete");

    commandHistory()->beginMacro(description);
    foreach (QWidget *w, widget_list) {
        emit widgetRemoved(w);
        DeleteWidgetCommand *cmd = new DeleteWidgetCommand(this);
        cmd->init(w);
        commandHistory()->push(cmd);
    }
    commandHistory()->endMacro();
}

В комментарии у них написано, что они используют макро, т.е. объединение комманд, потому что некоторые компоненты (например, редактор сигналов-слотов) соединены с сигналом widgetRemoved(w) и добавляют свои комманды (например, удаление connections виджетов).

Но это те коннекты, который создает пользователь(. Они на форме не работают, а пишутся в ui файл.
« Последнее редактирование: Июнь 20, 2012, 09:59 от nata267 » Записан
alexis031182
Гость
« Ответ #31 : Июнь 20, 2012, 09:03 »

Это понятно, как раз проблемы в дисконекте виджетов/объектов нет. Проблема в восстановлении конектов по активации undo. Если получение объектов, которые подключены к сигналам "удаляемого" объекта, ещё наверное возможно, то вот получение объектов, подключенных к его слотам - нет. Точнее сказать, что эта информация находится в приватной части QObject и просто так доступа к ней не получить. Это либо править исходники Qt, либо писать враппер для connect(). Оба способа естественно левые.
Записан
nata267
Гость
« Ответ #32 : Июнь 20, 2012, 10:09 »

А о каких именно коннектах вы говорите? Приведите пример?
Записан
alexis031182
Гость
« Ответ #33 : Июнь 20, 2012, 10:15 »

А о каких именно коннектах вы говорите? Приведите пример?
QObject::connect(), который может быть вызван родителем "удаляемого" объекта или вообще в альтернативной реальности Улыбающийся Как тогда узнать, к кому своими слотами подключен объект/виджет? Просто так - никак. А значит о восстановлении копии состояния объекта/виджета после фактического delete не может быть и речи.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #34 : Июнь 20, 2012, 12:08 »

А не допускаете ли Вы (ну или мы) ошибок в проектировании? Почему уткнулись носом в одну-единственную проблему (как восстановить сигналы)? Это может съесть все время и силы. Может есть смысл посмотреть - а какие еще проблемы?

Ну напр один объект содержит указатель(и) на  другой (наверное это Алексей называет "перекрестные ссылки"). Тут возможны варианты - напр при удалении держащего тот всегда удаляет и указатель. Или не удаляет никогда. Или когда счетчик ссылок на указатель станет = 0. Как это все выглядит с точки зрения undo?
Записан
nata267
Гость
« Ответ #35 : Июнь 20, 2012, 12:28 »

А о каких именно коннектах вы говорите? Приведите пример?
QObject::connect(), который может быть вызван родителем "удаляемого" объекта или вообще в альтернативной реальности Улыбающийся Как тогда узнать, к кому своими слотами подключен объект/виджет? Просто так - никак. А значит о восстановлении копии состояния объекта/виджета после фактического delete не может быть и речи.

вообще-то я и так понимаю о чем речь, я имею в виду вы можете привести конкретный пример.
вот к примеру. у меня я на форме разместила текстовое поле по двойному нажатию на которое у меня выскакивает редактор текста этого окна. если я вместо удаления спрячу это текстовое поле, то соответственно пользователь уже не сможет на него нажать и сгенерировать это событие или сигнал. в данном случае этот коннект никому не мешает. вот я и спрашиваю конкретный пример коннекта, который может повлечь ошибки, рассматриваz вариант с hide()

может быть в слотах проверять состояние объекта, и в зависимости от этого выполнять или не выполнять действия?? но опять же я рассматриваю вариант с hide()
« Последнее редактирование: Июнь 20, 2012, 12:43 от nata267 » Записан
nata267
Гость
« Ответ #36 : Июнь 20, 2012, 12:35 »

А не допускаете ли Вы (ну или мы) ошибок в проектировании? Почему уткнулись носом в одну-единственную проблему (как восстановить сигналы)? Это может съесть все время и силы. Может есть смысл посмотреть - а какие еще проблемы?

Ну напр один объект содержит указатель(и) на  другой (наверное это Алексей называет "перекрестные ссылки"). Тут возможны варианты - напр при удалении держащего тот всегда удаляет и указатель. Или не удаляет никогда. Или когда счетчик ссылок на указатель станет = 0. Как это все выглядит с точки зрения undo?

как мы можем удалить указатель, а если этот объект должен существовать независимо от удаляемого??
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #37 : Июнь 20, 2012, 12:44 »

вообще-то я и так понимаю о чем речь, я имею в виду вы можете привести конкретный пример.
Усложним немного учебный пример undo. Допустим если мы тащим Rectangle - мы хотим чтобы остальные фигуры двигались тоже. Ну вот мы и получили тот самый случай.

Обратите внимание что alexis031182 не тратит время на изучение типа "а какие частные случаи возможны", а подходит к деактивации принципиально - никаких сигналов не должно быть получено вообще. Однако мне кажется этого недостаточно. "Хороший индеец - мертвый индеец". Мочить надо, а не цацкаться перенося туда-сюда
Записан
alexis031182
Гость
« Ответ #38 : Июнь 20, 2012, 12:46 »

А не допускаете ли Вы (ну или мы) ошибок в проектировании? Почему уткнулись носом в одну-единственную проблему (как восстановить сигналы)? Это может съесть все время и силы. Может есть смысл посмотреть - а какие еще проблемы?
А я обычно так всегда утыкаюсь и бъюсь до потери пульса, пока не решу или буду вынужден отступить Смеющийся

Ну напр один объект содержит указатель(и) на  другой (наверное это Алексей называет "перекрестные ссылки").
Александр Улыбающийся Перекрёстные - да, когда друг на друга.

Тут возможны варианты - напр при удалении держащего тот всегда удаляет и указатель. Или не удаляет никогда. Или когда счетчик ссылок на указатель станет = 0. Как это все выглядит с точки зрения undo?
По идее, проблема с восстановлением сигналов возникла из-за того, что пока не придумали (я во всяком случае), каким образом можно получить информацию о конектах объекта (т.е. без какого-либо изврата). Если такие данные будут доступны, то восстановление работы через сигналы не видится сложным. Наверное аналогично и с перекрёстными указателями. Надо сохранять всю информацию об объекте, в т.ч. и всяческие указатели.

Но как всегда проблема только кажется легко решаемой. Когда объект помещается в корзину (удаляется через delete, но информация о нём где-нибудь сохранена) его родитель будет автоматом проинформирован об этом, и тот в свою очередь уже сам обнулит указатель. Но хуже обстоит ситуация со сторонними объектами, которые могут "глядеть в сторону" рассматриваемого нами подопытного. Конечно их всех можно "посадить" на сигнал QObject::destroyed(QObject *obj = 0), но это опять будет решение, притянутое за уши. В общем проблема, которая говорит, что между объектами должно быть как можно меньше ссылок друг на друга. Не то что даже перекрёстных, а просто, когда один на другого ссылается. Всё должно идти через посредника, который был бы озадачен разруливанием вот таких вот связей.
Записан
alexis031182
Гость
« Ответ #39 : Июнь 20, 2012, 12:56 »

вообще-то я и так понимаю о чем речь, я имею в виду вы можете привести конкретный пример. вот к примеру. у меня я на форме разместила текстовое поле по двойному нажатию на которое у меня выскакивает редактор текста этого окна. если я вместо удаления спрячу это текстовое поле, то соответственно пользователь уже не сможет на него нажать и сгенерировать это событие или сигнал. в данном случае этот коннект никому не мешает. вот я и спрашиваю конкретный пример коннекта, который может повлечь ошибки, рассматриваz вариант с hide()
Если Ваше текстовое поле будет подключено к ещё каким-либо сигналам, то в скрытом состоянии оно продолжит их принимать и обрабатывать. Таким образом, нажав как-нибудь на undo, пользователь увидит совсем не то текстовое поле, что ранее было скрыто.

может быть в слотах проверять состояние объекта, и в зависимости от этого выполнять или не выполнять действия?? но опять же я рассматриваю вариант с hide()
Вы везде стремитесь к концептуальным решениям, отличающимся гибкостью и изрядной долей изящества, но вставка if-проверки в слоты во всех мыслимых виджетах таковым решением не является.
Записан
alexis031182
Гость
« Ответ #40 : Июнь 20, 2012, 12:57 »

как мы можем удалить указатель, а если этот объект должен существовать независимо от удаляемого??
Имелось ввиду обнуление указателя.
Записан
alexis031182
Гость
« Ответ #41 : Июнь 20, 2012, 13:06 »

Усложним немного учебный пример undo. Допустим если мы тащим Rectangle - мы хотим чтобы остальные фигуры двигались тоже. Ну вот мы и получили тот самый случай.
Как и написал выше, нужен посредник. Если объекты будут ссылаться напрямую, то не получится восстановить (да и даже сохранить) ссылочную целостность при undo объекта.

Обратите внимание что alexis031182 не тратит время на изучение типа "а какие частные случаи возможны", а подходит к деактивации принципиально - никаких сигналов не должно быть получено вообще.
Да, потому что виджет виджету рознь. С парой десятков объектов может и прокатит if, блокирующий сигнал в слотах, но когда-нибудь это дело навернётся точно. Лучшее решение проблемы - это исключить возможность её появления в принципе.

Однако мне кажется этого недостаточно. "Хороший индеец - мертвый индеец". Мочить надо, а не цацкаться перенося туда-сюда
Я тоже именно за удаление. Это решает все проблемы с блокировкой сигналов (и событий тоже) автоматом. Но вот восстановление как произвести... Какую-то глобальную карту надо иметь обо всех конектах.
Записан
nata267
Гость
« Ответ #42 : Июнь 20, 2012, 13:17 »

вообще-то я и так понимаю о чем речь, я имею в виду вы можете привести конкретный пример.
Усложним немного учебный пример undo. Допустим если мы тащим Rectangle - мы хотим чтобы остальные фигуры двигались тоже. Ну вот мы и получили тот самый случай.

подождите, но ведь тогда посдеднем в стеке undo будет не удаление, а перетаскивание rectangle и только вернув его обратно, мы можем вернуть обратно объект.
Записан
alexis031182
Гость
« Ответ #43 : Июнь 20, 2012, 13:19 »

подождите, но ведь тогда посдеднем в стеке undo будет не удаление, а перетаскивание rectangle и только вернув его обратно, мы можем вернуть обратно объект.
Конечно, но это к частному вопросу о позиционировании. А мы упёрлись в проблему воссоздания объекта.
Записан
nata267
Гость
« Ответ #44 : Июнь 20, 2012, 13:20 »

а если нужно другое поведение, если нужно чтобы он в удаленном состоянии передвинулся. допустим у нас есть контейнер, который содержит набор виджетов. один мы удалили, контейнер передвинули в другое место, виджет восстановили. он должен быть в контейнере, а не за его пределами
Записан
Страниц: 1 2 [3] 4   Вверх
  Печать  
 
Перейти в:  


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