QT: отображаем одни и те же данные в разных компонентах
Для иллюстрации MVC-подхода не обязательно программировать отдельные классы, как в этом примере с матрицей. Во встроенные model-based виджеты модель, в конце концов, уже "зашита", и достаточно привыкнуть обращаться к данным через эту "лишнюю", а на самом деле, вовсе не лишнюю сущность.
В качестве примера разработаем список, который может отображаться в двух видах – компоненте QT ListView
и классическом выпадающем списке ComboBox
. При этом доступ к данным мы будем получать через модельные индексы, уже "заложенные" во все model-based компоненты.
Создав проект на шаблоне QWidget
, разработаем в дизайнере форм окно приложения.
Напомним, что выделить на форме несколько компонент можно при зажатой клавише Ctrl, сгруппировать их в горизонтальный блок нажатием Ctrl+H, а в вертикальный – нажатием Ctrl+L. Вид формы показан на рисунке:
форма виджета SimpleModelWidget
По списку объектов справа на картинке легко увидеть, какие компоненты мы использовали.
В описании класса widget.h
предусмотрим ссылку на модель и слоты для обработки нажатий кнопок:
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QtWidgets> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; QStringListModel *model; //модель списка private slots: //слоты для действий void insertData(); void updateData(); void deleteData(); }; #endif // WIDGET_H
В реализации класса widget.cpp выполним следующее:
- инициализируем модель и назначим её двум компонентам –
ListView
иComboBox
; - свяжем клики по кнопкам со слотами.
В коде слотов обратите внимание на то, что вся нужная информация о данных получается только через модельные индексы.
Так как ListView
и ComboBox
привязаны к одной и той же модели, по завершении редактирования элемента списка изменения отобразятся и в ComboBox
! При удалении элементов списка нам также не придётся заботиться о ComboBox
, изменения в нём произойдут автоматически.
Вот полный листинг файла widget.cpp
:
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); model = new QStringListModel(this); //создали модель QStringList list; model->setStringList(list); //инициализировали пустым списком ui->listView->setModel(model); //назначили модель ui->comboBox->setModel(model); //двум компонентам! ui->listView->setEditTriggers (QAbstractItemView::DoubleClicked|QAbstractItemView::AnyKeyPressed); //разрешили редактировать список двойным щелчком и клавишей connect(ui->insertButton,SIGNAL(clicked()),this,SLOT(insertData())); connect(ui->updateButton,SIGNAL(clicked()),this,SLOT(updateData())); connect(ui->deleteButton,SIGNAL(clicked()),this,SLOT(deleteData())); } Widget::~Widget() { delete model; delete ui; } void Widget::insertData(void) { int row = model->rowCount(); //узнали количество строк model->insertRows(row,1); //добавили 1 строку в конец QModelIndex i = model->index(row); //узнали её индекс ui->listView->setCurrentIndex(i); //и разрешили ui->listView->edit(i); //редактировать } void Widget::updateData(void) { int row=ui->listView->currentIndex().row(); //узнали текущую строку списка QModelIndex i = model->index(row); //и нашли её в модели ui->listView->setCurrentIndex(i); //и разрешили ui->listView->edit(i); //редактировать } void Widget::deleteData(void) { int row=ui->listView->currentIndex().row(); //узнали текущую строку списка model->removeRows(row,1); //и удалили её из модели }
Для "обратной реакции" ListView
на ввод данных из ComboBox
мы тоже ничего не будем программировать отдельно, а просто допишем пару строк в конструкторе виджета, например, таких:
ui->comboBox->setEditable(true); connect(ui->comboBox,SIGNAL(accepted()),this,SLOT(insertData()));
Теперь новые элементы можно вводить и в ComboBox
, а по нажатию клавиши Enter они будут немедленно отображаться в ListView
.
Скачать папку проекта QT5 SimpleModelWidget в архиве .zip (3 Кб)
21.04.2017, 14:25 [4255 просмотров]