Модели Qt с переплетенными обновлениями - PullRequest
0 голосов
/ 01 апреля 2020

Я довольно новичок в Qt и пытаюсь понять, как мне строить свои модели. Вот ситуация (я полностью владею всем).

У меня есть класс данных, который выглядит примерно так:

class Data
{
public:
    Data();

    void addValue(int newValue);
    void removeValue(int indexToRemove);
    // Other access functions

private:
    void recalculate();

    QList<int> values;
    int aggregatedValue;
};

Функции publi c добавляют или удаляют значения из QList и вызов приватной функции, которая пересчитывает агрегированное значение (в противном случае недоступное), которое является статистическим индексом списка - думайте о нем как о среднем значении списка.

Теперь мне нужно построить модели чтобы показать эти данные.

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

Будучи неспособным заставить работать модель дерева, я построил две различные модели, listModel и aggregatedModel, причем последняя является моделью только для чтения. Проблема в том, как заставить принудительно обновить виджет, используя aggregatedModel, когда в список вставляется новое значение?

Я предложил 2 решения: создать супер модель, которая отвечает за подключение listModel и aggregatedModel, то есть класс, который перехватывает сигналы dataChanged() от listModel, вызывает recalculate(), а затем излучает сигналы dataChanged() от aggregatedModel, чтобы принудительно обновить представления; или сделать Data класс QObject, чтобы иметь возможность отправлять сигнал при изменении агрегированного значения (внутри recalculate()) и подключать aggregatedModel к нему.

Вопрос 2 : какое решение наиболее распространено? Мне нравится идея иметь фактический класс данных как чистый класс C ++, то есть не QObject, поэтому никаких накладных расходов, гораздо более переносимый через проекты - но последнее решение кажется более гибким и простым в организации, с дополнительным преимуществом, которое если я использую разные модели для отображения / редактирования одной и той же информации, я могу легко это сделать.

Вопрос 3 : предположим, у меня есть второй класс данных, PooledData, который объединяет определенные значения из многих Data объектов. Он содержит указатели на объединенные данные (фактические данные - это не просто целые числа, а более сложные структуры). Кроме того, я должен построить модель, которая реагирует на изменения данных, на которые указывают. Как я могу это сделать?

1 Ответ

1 голос
/ 01 апреля 2020

Вы должны быть в состоянии сделать это с одной моделью. Я бы выделил подкласс QAbstractItemModel, а в функции setData, где вы будете реагировать на изменения в списке, будет выдан сигнал dataChanged как для измененного элемента списка, так и для индекса, представляющего агрегированное значение. Я бы определенно НЕ заставлял мой класс Data излучать сигналы сам, если бы он управлялся моделью. Обработка пользовательского ввода и сигнализация изменений в базовых данных - это строго работа модели.

Для вашего второго вопроса я лично хотел бы использовать классы не-Qt для хранения фактических данных, а затем использовать модели Qt как интерфейсы между моими классами и прокси-моделями, представлениями и т. д. c. Я уверен, что именно так предполагается использовать всю систему просмотра моделей.

Для вашего третьего вопроса просто подключите сигнал dataChanged от вашей модели данных к слоту в модели объединенных данных. Этот слот должен выполнить все соответствующие вычисления, а затем подать другой сигнал, что он изменился. Если вы правильно настроите все сигналы от первой модели, то во второй модели будет довольно легко правильно реагировать на них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...