вторник, 23 сентября 2008 г.

Реализация раздела "Заказчики". Часть 2

2. Форма для добавления и редактирования данных по заказчикам.

Связать модель с такими виджетами, как TableView или ListView - легко и просто, достаточно только вызвать setModel() и проблема решена. Но как быть, если виджет представляет из себя форму, на которой размещены комбобоксы, лайнедиты и т.п.? Как установить связь менжду этими элементами и SQL-данными? 
Реализовать подобное можно двумя способами: 1) не используя QDataWidgetMapper и 2) используя QDataWidgetMapper. Далее - описание второго способа.
Итак, есть виджет, на котором размещены несколько lineEdit. Каждый из них нам нужно связать с той или иной колонкой из таблицы "customers": 
lineEdit - название заказчика, lineEdit_1 - город заказчика, ну и т.д. 

QDataWidgetMapper *mapper = new QDataWidgetMapper(this); // создаем в конструкторе виджета маппер
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); // определяем стратегию обновления данных
mapper->setModel(model); // назначаем модель с таблицей "customers"

Используя метод addMapping(), установим связь между  lineEdit и колонками таблицы:

mapper->addMapping(ui.lineEdit, 0); // имя заказчика
mapper->addMapping(ui.lineEdit_1, 1); // город
mapper->addMapping(ui.lineEdit_2, 2); // улица
mapper->addMapping(ui.lineEdit_3, 3); // офисный телефон
mapper->addMapping(ui.lineEdit_4, 4); // факс
mapper->addMapping(ui.lineEdit_5, 5); // имя контактного лица
mapper->addMapping(ui.lineEdit_6, 7); // мобильный номер
mapper->addMapping(ui.lineEdit_7, 8); // майл
mapper->addMapping(ui.textEdit, 9); // примечание

После того, как мы связали лайнедиты с табличными колонками, осталось только назначить мапперу табличный индекс. Продемонстрируем это на примере открытия записи заказчика из таблицы "Все заказчики" - метод OpenCustomer(QModelIndex), назначенный в качестве слота сигналу doubleClicked виджета tableView:

connect(ui.tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OpenCustomer(QModelIndex)));

После двойного клика на строке виджета tableView в метод OpenCustomer передается текущий индекс из модели, которая была задана виджету. Остается только передать этот индекс маппер, но... В маппер в качестве модели мы назначили QSqlTableModel, а виджету tableView - QSortFilterProxyModel. Чтобы избежать ошибки, необходимо перевести индекс из QSortFilterProxyModel в индекс QSqlTableModel:

QModelIndex index2 = proxyModel->mapToSource(index); // переводим текущий index из QSortFilterProxyModel в QSqlTableModel
mapper->setCurrentModelIndex(index2); // назначаем индекс мапперу

Теперь в лайнедитах отображаются данные из строки, выделенной в виджете tableView. Выше мы выбрали "ручную" стратегию сохранения, таким образом, для того, чтобы изменения в лайнедитах вступили в силу - необходимо вызвать метод submit().

Комментариев нет: