Эквивалент CancelEvent в сигналах Qt

Я обычно привык к .net framework и недавно получил возможность работать над проектом с использованием C ++ / Qt. В этом контексте я хочу реализовать следующую функциональность: (для упрощения вещей, скажем, у меня есть ListView и Textbox / Textedit)

  • Если я выберу элемент ListView -> показать соответствующий текст в textedit (сделанный)
  • Если я отредактирую текст и нажму на другой элемент в списке -> покажу диалоговое окно с вопросом, сохранить или отменить изменения (сделанный). Textedit получает сигнал из списка, сообщающий, что выбранный элемент изменился.
  • Если пользователь нажимает сохранить -> сохранить его обратно и обновить элемент в списке, новый элемент, по которому щелкнул пользователь, будет выбран в списке (сделанный)
  • Если пользователь нажимает «Отмена» -> не выбирайте другой элемент, по которому пользователь нажал (вот где моя проблема)

В основном я вижу два решения (может быть больше) для этого:

  • Отправьте сигнал обратно из textedit в список, сообщив списку, чтобы восстановить предыдущий выбор. Мне лично не очень нравится это решение, потому что я должен соединить их сильнее (список посылает сигналы в textedit, а теперь и наоборот). Кроме того, это «принудительное» восстановление выбора может снова вызвать последующие сигналы, которые должны быть снова заблокированы …
  • Гораздо более удачным решением (я думаю) было бы иметь какой-то механизм вето в сигналах. Я мог бы представить список для отправки двух сигналов:
    • давайте назовем первый aboutToChangeSelection(proposedSelection, vetoObj)
    • и еще один после того, как действие сделано: changedSelection(newSelection)

Первый сигнал будет отправлен на textedit, который затем в конечном итоге будет использовать свое право вето. После этого тот же сигнал будет отправлен в сам список, выполнить действие в зависимости от права вето и отправить второй сигнал, если он фактически изменил выбор.

В мире .NET существует такой механизм, с помощью CancelEventArgs. Я знаю, что у событий .NET и сигналов Qt совершенно другой принцип работы, но есть ли какой-нибудь эквивалент Qt для достижения такого же эффекта?

Большое спасибо за любую помощь!

5

Решение

Если вы используете QListWidget вместо QListViewтогда вы можете сделать следующее:

  • слушать сигнал: QListWidget::itemPressed ( QListWidgetItem * item ) а не сигнал о том, что предмет изменился (т.е. currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous ) в моем примере)
  • Функция, открывающая диалог — это слот, связанный с этим сигналом. Я не думаю, что это нужно изменить.
  • Слушайте сигнал: currentItemChanged ( QListWidgetItem * current, QListWidgetItem * previous ) который будет использоваться только для запоминания текущего и последнего элемента.
  • Теперь в вашем случае, когда пользователь установил отмену, программно вернитесь к последнему пункту.

Теперь есть одна проблема. Какой сигнал будет получен первым ?? Не указано в документе и может быть в любом порядке. Если пользователь на элементе Aи нажимает на элемент BВы хотите, чтобы Lastitem был Aи текущий элемент будет B на данный момент вы обрабатываете itemPressed, Итак, вы хотите справиться currentItemChanged первый. К счастью, вы можете использовать Qt::DirectConnection за currentItemChanged и использовать Qt::QueuedConnection за itemPressed

АЛЬТЕРНАТИВА:

Вы можете использовать фильтр событий в списке виджетов. Этот фильтр будет выполнять обработку, описанную вами в нескольких шагах. Если пользователь нажимает «Принять», вы отправляете событие в список. Если пользователь отклоняет, вы блокируете событие. Я не уверен, но возможно, что события не будут обработаны фильтром, который сделает эту альтернативу нежизнеспособной.

1

Другие решения

Не уверен на 100%, но вы можете переопределить QCoreApplication::notify( QObject * receiver, QEvent * event ) и попробуйте найти подходящее событие и просто позвонить ignore() в теме. И чтобы сказать, когда игнорировать, вы можете добавить новый QEvent подкласс, вставьте в него указатель целевых элементов и сделайте так, чтобы он действовал как событие вето — если оно получено, вы знаете, что будете игнорировать следующее событие определенного типа для этого конкретного объекта.

0

По вопросам рекламы [email protected]