Основная концепция модели/представления Qt и QTableView

Я хочу создать программное обеспечение, которое будет просматривать некоторые таблицы базы данных, и пользователи смогут редактировать эти таблицы. Прочитав эту ссылку, я подумал, что model/view был хорошим подходом к тому, что мне нужно. Посмотрите на следующий макет: введите здесь описание изображения

Зная это, у меня есть вопросы, чтобы убедиться, что я понимаю концепцию. Пожалуйста, скажите мне, если я в хорошем направлении:

  1. Думаю, мне нужно создать класс модели для каждой из моих таблиц? (подкласс QAbstractModel). Это будет выглядеть так:

    class citiesTableModel : public QAbstractItemModel
     {
         Q_OBJECT
     }
    
  2. Конструктор cityTableModel будет извлекать данные из таблицы в базе данных?

    QAbstractItemModel *model = new citiesTableModel(); //model will contain 2 rows, New York and Seattle
    
  3. Нужно ли создавать подклассы QTableView для каждой модели?

    class citiesTableView : public QTableView{}
    
  4. Наконец, я предполагаю, что нужно переопределить view.setData и view.setModel? setModel будет перебирать каждую строку модели для построения QTableView, а setData будет выполнять правильный запрос для добавления новых данных в модель?

Большое Вам спасибо.


person peterphonic    schedule 20.03.2013    source источник


Ответы (2)


Для этого вы можете использовать QSqlTableModel.

Как говорится в документе, его можно использовать довольно просто:

QSqlTableModel *model = new QSqlTableModel(parentObject, database);
model->setTable("employee");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

QTableView *view = new QTableView;
view->setModel(model);
view->hideColumn(0); // don't show the ID
view->show();

Думаю, мне нужно создать класс модели для каждой из моих таблиц?

Да, одна модель представляет собой одну таблицу sql.

Конструктор cityTableModel будет извлекать данные из таблицы в базе данных?

QSqlTableModel сделает это за вас:

QSqlTableModel *model = new QSqlTableModel(parentObject, database);
model->setTable("employee");
model->select();

Нужно ли создавать подклассы QTableView для каждой модели?

Нет, не знаешь. Один QTableview может отображать любую модель, которую вы установили с помощью setModel.

Наконец, я предполагаю, что нужно переопределить view.setData и view.setModel? setModel будет перебирать каждую строку модели для построения QTableView, а setData будет выполнять правильный запрос для добавления новых данных в модель?

В зависимости от стратегии редактирования, установленной с помощью setEditStrategy, изменения будут зафиксированы при редактировании ячеек таблицы или после их отправки с помощью submitAll.

Кроме того, вы можете взглянуть на QDataWidgetMapper. Он может сопоставлять данные вашей модели с различными виджетами и отслеживать изменения, которые вы делаете, редактируя эти виджеты.

person hank    schedule 20.03.2013
comment
Спасибо за ваш ответ. На самом деле это выглядит немного проще, чем я думал. Вопрос: Наша база данных — postgreSQL. Знаете ли вы, работает ли QSqlTableModel с этой базой данных? Кроме того, для стратегии редактирования на самом деле невозможно будет изменить само табличное представление, только с помощью формы (табличное представление ниже). Делает ли это еще проще? Наконец, вы уверены, что мне не нужно создавать подклассы QTableView? Если я хочу преобразовать логическое значение в флажок? Спасибо - person peterphonic; 20.03.2013
comment
Да, он может работать с любой базой данных, если у вас есть соответствующий плагин qt sql. Да, можно редактировать данные через таблицу. Чтобы отобразить логические значения в виде флажков, вы должны использовать делегировать классы. - person hank; 20.03.2013
comment
Еще раз спасибо за ваш ответ. Что-то, что я не был достаточно ясно. Собственно, это дизайнерское решение. Что мы хотим: пользователь НЕ сможет редактировать само табличное представление. Пользователь должен будет сначала выбрать строку, и форма будет заполнена соответствующим образом, и пользователь изменит форму. - person peterphonic; 20.03.2013
comment
Должен ли submitAll быть членом QTableView, потому что я не могу его найти? - person Paul-Sebastian Manole; 09.12.2014

В основном у вас есть разные варианты:

Либо ваша база данных является базой данных SQL. Вы можете использовать подкласс QSqlTableModel. В противном случае, если вы хотите создать свою модель с нуля, вы делаете свою собственную модель, но я не вижу смысла. У вас также есть QTableModel с примером.

Вам не нужно создавать модель для каждой таблицы, потому что это всегда модель таблицы. Модель в основном определяет, как вы можете добавлять и удалять строки с вашими конкретными данными.

Что касается представления, вам придется наследовать QTableView, чтобы добавить собственное поведение для ваших строк и столбцов, например, например, события перетаскивания.

Единственный элемент настройки, который вам нужен, — это делегат для вашего представления или только для столбца. Это в основном преобразует логическое значение в вашей модели в флажок.

Я предлагаю вам посмотреть на делегата SpinBox для большей точности.

Надеюсь это поможет.

Редактировать:

В случае PostgreSQL вы можете добавить его в QsqlDatabase:

 QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
 db.setHostName("acidalia");
 db.setDatabaseName("customdb");
 db.setUserName("mojito");
 db.setPassword("J0a1m8");
 bool ok = db.open();

Затем передайте БД в QSqlTableModel. Если вам нужна более реляционная операция, например выборка полей из внешнего ключа, вы можете использовать:

QSqlRelationalTableModel
QSqlRelationalDelegate
person Kirell    schedule 20.03.2013