Условие if-else в цикле: будущие итерации перезаписывают результаты предыдущих итераций

Я пытаюсь выделить selectedItem и его дети среди списка items.

const QList<Item *> items = /* ... */;
Item *selectedItem = /* ... */;

Q_FOREACH( Item *item, items ) {
    if ( selectedItem == item ) {
        item->setHighlightEnabled(true); // Highlight selected item
    } else {
        item->setHighlightEnabled(false); // De-highlight other items
    }
}

Метод item->setHighlightEnabled рекурсивно делает то же самое для детей:

void Item::setHighlightEnabled(bool enabled)
{
    if (enabled) {
        /* highlight item */
    } else {
        /* de-highlight item */
    }

    // Go through all children and highlight them too
    Q_FOREACH (Item *child, children())
        child->setHighlightEnabled(enabled);    

}

Работает нормально, но есть баг. Мы перебираем элементы все. Когда родитель выбран, родитель и его дочерние элементы выделяются. Но затем цикл продолжает перебирать детей. Поскольку дочерние элементы НЕ выбраны, поэтому они не выделяются (перезаписывая выделение в предыдущих итерациях цикла). Интересно, как лучше всего это исправить.

Что, если вы проверите статус выделения перед его изменением?

vahancho 22.05.2019 11:04

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

Marek R 22.05.2019 11:09

@vahancho Предположим, что элемент X ранее выбран (выделен) пользователем, затем пользователь щелкает элемент Y. Элемент Y (и его дочерние элементы) необходимо выделить, а элемент X необходимо отменить выделение. Таким образом, статус выделения не является надежной вещью для проверки.

user3405291 22.05.2019 11:09

Я подозреваю это проблема.

Marek R 22.05.2019 11:11

@user3405291 user3405291, если y1 является дочерним элементом Y, проверьте, выделено ли оно, прежде чем изменять его статус, чтобы избежать переключения статуса.

vahancho 22.05.2019 11:14

Придирка: я действительно ненавижуif (children().size()) Q_FOREACH .... Безусловный цикл делает то же самое

Caleth 22.05.2019 11:20

Разве selectedItem не является одним из указателей в items? Есть ли несколько «элементов» с одним и тем же именем?

molbdnilo 22.05.2019 11:22

@molbdnilo У нас есть проверка имен, чтобы убедиться, что нет повторяющихся имен. Но вы правы, может быть, достаточно просто сравнивать указатели (а не сравнивать имена)?

user3405291 22.05.2019 11:27
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
5
8
131
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Насколько я понимаю вашу проблему, вы можете использовать for-loops. В первом вы снимаете выделение со всех элементов. А второй вы оставляете как есть и просто останавливаете его с помощью оператора break;, как только он найдет выбранный элемент.

Ответ принят как подходящий

Сначала снимите выделение всего, а затем выделите текущий выбор.

Если selectedItem уже является указателем на единственный элемент, который вы хотите выделить, вам не нужно его искать, вам нужно только:

Q_FOREACH (Item *item, items)
    item->setHighlightEnabled(false);
selectedItem->setHighlightEnabled(true)

Другие вопросы по теме