crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> QDataWidgetMapper и изменение foregn key
Begemot
  опции профиля:
сообщение 28.5.2010, 17:44
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 13
Регистрация: 15.5.2010
Пользователь №: 1718

Спасибо сказали: 0 раз(а)




Репутация:   0  


Случилось тут проблема, и уже больше суток не могу решить, пробовал разные подходы все или вообще не работает или работает но через раз (не шучу).

Есть MySqlRelationalTableModel, у нее одно из полей внешний ключ (fkey) ну и соответвенно связанная таблица ID, Name. Все поля таблицы привязаны к виджетам на форме через QDataWidgetMapper, fkey привязан к QLineEdit. Отображается все отлично, вместо значения ключа я вижу соответвующий Name из связанной таблицы.

Вопрос как правильно програмно изменить это значение. Для юзера это выглядит так - QLineEdit read only, по щелчку на нему - открывается диалог, в котором список Name - пользователь выбирает нужное или _вводит новое_, я получаю строку которую он выбрал\ввел. Как мне теперь правильно изменить значение в главной модели и все это сохранить в бд?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Litkevich Yuriy
  опции профиля:
сообщение 28.5.2010, 18:59
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


setModelData и submitAll
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Begemot
  опции профиля:
сообщение 29.5.2010, 7:39
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 13
Регистрация: 15.5.2010
Пользователь №: 1718

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 28.5.2010, 18:59) *
setModelData и submitAll


Я так полагаю что речь идет о делегате, потому как setModelData есть только у наследников QAbstractItemDelegate. Но из контрола (наследник QLineEdit) к делегату доступ получить вроде нельзя (не передавая его руками)? да это и не важно, в принципе, setModelData вызовется автоматически при потере контролом фокуса, использую setEditStrategy(QSqlTableModel::OnFieldChange);

Сейчас работа идет так, в классе наследнике QEditLine перехватывается щелчек мыши, показывается диалог - пользователь выбирает строку, эта строка записывается в наш QLineEdit, дальше ждем потери фокуса, для автоматического сохранения.

У меня есть свой делегат (изначально писался для обслуживания комбобоксов), для этого поля добавляю туда такой код
CODE

void DogDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
switch(index.column())
{
......

case Animals_Breed:
QString text = editor->property("text").toString();
qDebug()<<"save Animals_Breed " << text;

// --- get relation table and try to find our string
QSqlTableModel * rm = ((QSqlRelationalTableModel *)model)->relationModel(Animals_Breed);
QModelIndexList indexList = rm->match(rm->index(0, Breeds_Breed), Qt::DisplayRole, text, 1, Qt::MatchExactly);
int id = 0;
if (!indexList.isEmpty())
id = rm->data(rm->index(indexList.first().row(), Breeds_Id)).toInt();
else
{ // there is no such string - we should add it
QSqlRecord record(rm->record());
record.setValue(Breeds_Breed, text);
rm->insertRecord(0, record);
rm->submit();

// --- Get id for new added string
QModelIndexList indexList = rm->match(rm->index(0, Breeds_Breed), Qt::DisplayRole, text, 1, Qt::MatchExactly);
if (!indexList.isEmpty())
id = rm->data(rm->index(indexList.first().row(), Breeds_Id)).toInt();
else
Q_ASSERT(0);
}

model->setData(index, id);
((QSqlRelationalTableModel*) model)->submitAll();
return;

}
QItemDelegate::setModelData(editor, model, index);
}


Если маппер пытается сабмитить это поле, я получаю в rm таблицу связанную с внешним ключем, и пытаюсь в соответвуюшей колонке найти значение которое у нас в лайнэдите. Если значение есть - все отлично, беру соответсвующий id из внешней таблицы и пишу его в главную таблицу.
Если там такого значения нет, значит пользователь ввел новую породу - я добавляю ее в связанную таблицу, сабмичу ее, дальше получаю id и пишу в главную.

Этот подход работает если пользователь просто выбирает из списка строку (которая уже есть в таблице). Если же он вводит новую строку - я получаю проблемы :(
1. Строка добавляется в бд.
2. В едит бокс попадает соответвующее значение (уже прочитанное из бд, а не то что я руками поставил)
3. дальше пользователь ставит фокус в другой контрол, и потом когда фокус переходит в третий контрол - уходит из второго, значение в едит боксе и в базе данных сбрасывается в предыдущее, и так в 66% случаях.

submitAll не помогает :( видимо проблема в том что при изменении\сабмите связаной таблицы, то ли главная модель не обновляется то ли еще что - но оно "забывает" изменения в 2 их 3 случаях. Что делать ума не приложу, как-то ресетить модель? заново перезагружать? что-то еще? Или это просто еще 1 баг :(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.11.2024, 13:49