На этом шаге рассмотрим промежуточную модель данных.
В оригинальной модели может получиться так, что какой-либо из элементов находится первым, а нам нужно поместить его в конец или в середину. Изменение расположения данных в оригинальной модели данных вызовет изменения во всех присоединенных представлениях, что может быть нежелательно. В подобных случаях нам понадобится промежуточная модель.
Промежуточная модель — это модель, находящаяся между моделью данных и представлением (рис. 1). Такая модель предоставляет возможность выполнять манипуляции с данными, при этом не изменяя данные оригинальной модели.
Рис.1. Схема использования промежуточной модели
С ее помощью можно выполнить сортировку или перестановку данных. Таким образом можно сделать два представления: одно из которых показывает измененные данные, а другое — оригинальные.
Другая полезная операция, которую можно выполнить с помощью промежуточной модели, — это отбор элементов данных. Для этого в промежуточной модели необходимо установить критерии, с помощью которых будет осуществляться отбор. Класс QSortFilterProxyModel является обобщенной реализацией промежуточной модели, позволяющей выполнять сортировку и отбор. Для задания критериев отбора может быть использован слот QSortFilterProxyModel::setFilterRegExp(), в который передается объект регулярного выражения класса QRegExp.
При отборе модель возвращает индексы только тех строк, для которых текст в столбце соответствует указанному критерию. При сортировке порядок расположения осуществляется в соответствии со значениями элементов, расположенных в каждом столбце. Сортировку каждого столбца можно проводить по возрастанию и убыванию.
Программа, окно которой показано на рис. 2, осуществляет отбор тех элементов, имена которых начинаются на букву "M". В левой части окна программы представление отображает оригинальную модель, а в правой — промежуточную.
Рис.2. Отбор элементов
Рассмотрим текст приложения:
//создаем модель QStringListModel, которую инициализируем строковыми значениями QStringListModel model; model.setStringList(QStringList() << "Android" << "Linux" << "Windows" << "MacOSX" << "MSDOS" ); //создается промежуточная модель QSortFilterProxyModel QSortFilterProxyModel proxyModel; //с помощью метода setSourceMode() связывается с оригинальной моделью proxyModel.setSourceModel(&model); //для осуществления отбора элементов, начинающихся на букву "M", //в слоте setFilterWildcard() устанавливается маска "M*" proxyModel.setFilterWildcard("M*"); //создаем два представления QListView, в одном из них //устанавливаем оригинальную модель, а в другом — промежуточную QListView* pListView1 = new QListView; pListView1->setModel(&model); QListView* pListView2 = new QListView; pListView2->setModel(&proxyModel);
Файлы приложения можно взять здесь.
Создадим виджет текстового поля, с помощью которого пользователь сам бы устанавливал критерий для выборки (рис. 3).
Рис.3. Ввод критерия для выборки
В этом случае сигнал textChanged() нужно соединить со слотом setFilterWildcard() модели SortFilterProxyModel, что позволит при изменении критерия отбора, находящегося в текстовом поле, сразу же применить его.
... QLineEdit* pleText = new QLineEdit("M*"); ... QObject::connect(pleText, SIGNAL(textChanged(const QString&)), &proxyModel,SLOT(setFilterWildcard(const QString&)));
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим модель элементно-базированных классов.