Russian Qt Forum

Qt => Базы данных => Тема начата: Kilimangaro от Март 22, 2012, 12:58



Название: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 12:58
Мужики, имею вопрос!
Есть таблица courses в базе с такой структурой:
id_course
1
2
key
наличный
безналичный
value
8.2
9

Так же, есть таблица custommers с такой структурой:
id_custmmers
1
2
name
ООО Рога и Капыта
ООО Шарашкина Контора
id_course
1
2
Таблицу custommers я сократил конечно же, так как остальные колонки не относятся к делу.

Задача состоит в следующем: мне необходимо редактировать таблицу custommers, и делать это необходимо при помощи QSqlTableModel, QComboBox и конечно же QDataWidgetMapper. Я не думал, что у меня возникнут какие либо сложности. Задача показалась, мне до боли простой. Я в начале создал QComboBox получил данные из БД при помощи QSqlTableModel и задал QComboBox полученную модель, предварительно убедившись, что модель получает данные! Вот код:
Код:
    QSqlTableModel *boxCourseModel = new QSqlTableModel;
    boxCourseModel->setTable("courses");
    boxCourseModel->select();

    boxCourse->setModel(boxCourseModel)
После вывода окна диалога, в котором находится сей QComboBox, я получил список, в котором отображаются элементы из колонки id_course из таблицы courses. Видимо, это потому, что QComboBox при добовлении нового элемента, запрашивает в начале имя элемента (то, что будет отображаться в выпадающем меню QComboBox), а потом уже просит ключ этого поля. Запрашивая данные из БД, при помощи QSqlTableModel я получаю струткру данных иную key=>value что и наглядно видно на выходе.

Я не остановился на этом и добавил новый параметр QComboBox : boxCourse->setModelColumn(1);
Теперь, код определения QComboBox выглядит так:
Код:
    QSqlTableModel *boxCourseModel = new QSqlTableModel;
    boxCourseModel->setTable("courses");
    boxCourseModel->select();

    boxCourse->setModel(boxCourseModel);
    boxCourse->setModelColumn(1);
Я решил, что этим параметром, я указал какую колонку отображать в списке QComboBox, а другая колонка, мол будет ее идентификатором. Однако, оказалось это не так. Я так, понял, что при указании setModelColumn, как бы в QComboBox попадает, список, только этого набора данных, то есть попадает только поле name списком, а идентификаторы присваиваются автоматически самим QComboBox начиная с 0. Я радовался, когда все работало и отображалось, как нужно, но беда в том, что при использовании QDataWidgetMapper начали возникать трудности.
Код:
    QSqlTableModel *tempModel = new QSqlTableModel;
    tempModel->setTable("custommers");
    tempModel->setFilter("name = '"+string+"'");
    tempModel->select();

    QDataWidgetMapper *map = new QDataWidgetMapper;
    map->setModel(tempModel);
    map->addMapping(boxCourse, 4, "currentIndex");
    map->addMapping(boxTeams, 3, "currentIndex");
    map->toFirst();

Что я получаю? Получается, к примеру, что из таблицы (смотри выше) custommers я получаю данные, по полю name с именем "ООО Рога и Копыта" тем, самым получая из поля id_course я получаю цифру 1 и mapper пытается связать ее с моим QComboBox, в котором идентификатор 1, это уже не та еденица, которая в таблице id_courses, в поле id_course, исходя из идентификаторов самого QComboBox, отсчет которых начинается с нуля, это получается второй элемент, а второй элемент в моей таблице это совсем другой элемент! Вот и получается, что ничерта не получается!

Я для эксперимента изменил структуру таблицы courses поменяв местами столбики name и id_course, так работает все правильно, в новой структуре моя таблица выглядит вот так:
key
наличный
безналичный
id_course
1
2
value
8.2
9

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


Название: Re: QComboBox + ДБ
Отправлено: VozaMFC от Март 22, 2012, 14:10
А почему нельзя просто использовать класс QSqlQuery, а потом запросиком...


Название: Re: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 14:29
Пробовал
Код:
    QSqlQuery query("SELECT key, id_team FROM teams");
    while(query.next())
    {
        boxTeams->addItem(query.value(0).toString(), query.value(1).toString());
    }

Но, почему то QComboBox сам присвоил идентификаторы свои  :-\


Название: Re: QComboBox + ДБ
Отправлено: VozaMFC от Март 22, 2012, 14:36
Пробовал
Код:
    QSqlQuery query("SELECT key, id_team FROM teams");
    while(query.next())
    {
        boxTeams->addItem(query.value(0).toString(), query.value(1).toString());
    }

Но, почему то QComboBox сам присвоил идентификаторы свои  :-\
Да не может он себе позволить такую наглость...
Что возвращает QVariant   QComboBox::itemData(..) ? Т.е. проверяли?


Название: Re: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 14:45
Код:
qDebug() << boxCourse->itemData(1).toString();
??? вообще нечего не возвращает


Название: Re: QComboBox + ДБ
Отправлено: VozaMFC от Март 22, 2012, 14:52
Код:
qDebug() << boxCourse->itemData(1).toString();
??? вообще нечего не возвращает
2 выхода
1-й найти ошыбку
2-й предоставить код с студию(как обычно желательно минимальный компилируемый исходник из Вашей проблеммой).

Вообще ситуация тут елементарная, или не там берете или где то в другом месте кладете.


Название: Re: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 14:56
Я извиняюсь, я перепутал QComboBox  ::)

Код:
boxCourse->itemData(0);
Возвращает 1, если указать index = 0 и 2 если index = 1 соответственно!


Название: Re: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 14:59
То есть как я и говорил, ему по барабану, в качестве index у него присваиваются свои начиная с 0. И соответственно он мне подсовывает, не те значения в mapper. Я просто не пойму, задача вроде элементарная, а у меня какая-то нерешаемая проблема получилась :)


Название: Re: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 15:20
Вот исходник виджета, что бы проверить работу, необходимо в поле "Name" начать вводить что-то например "ООО Рога и Копыта".

Базу sqllite я упаковал, не упаковывал лишь подключение к ней


Название: Re: QComboBox + ДБ
Отправлено: Kilimangaro от Март 22, 2012, 15:36
В общем пока, что решил все это дело, таким образом:
Код:
boxTeams->addItem("---");
QSqlQuery query("SELECT key, id_team FROM teams");
    while(query.next())
    {
        boxTeams->addItem(query.value(0).toString(), query.value(1).toString());
    }

То есть добавил заведомо, левый элемент, с именем в виде прочерка, означающий, мол нечего не выбрано, при сохранении в БД, буду проверять, что бы не стояли прочерки и лишь потом записывать в БД. Но вопрос все же остается открытым, интересно где же я затупил. Потому, что однозначно я где-то туплю и вопрос решается элементарно!