Russian Qt Forum

Qt => Базы данных => Тема начата: ecspertiza от Июль 29, 2009, 16:18



Название: Кто как загружает QComboBox из БД
Отправлено: ecspertiza от Июль 29, 2009, 16:18
Вобщем интересут кто как загружает QComboBox из базы данных

я делаю так, у меня есть функция

Код:
void LoadComboBox(QComboBox *obj,QString str)
{
           obj->clear();
           QSqlQuery query;
           QString que;

           QStringList combolist;

           que = "select name from "+str+" order by id";


if (!query.exec(que))
{
QMessageBox::critical(this,tr("Error load param"),tr("Can not load param"));
}else
{
while (query.next())
{
combolist << query.value(0).toString();
}

obj->addItems(combolist);

for (int i = 0;i<combolist.count();i++)
{
obj->setItemData(i,combolist.at(i),Qt::ToolTipRole);
}

QCompleter *completer = new QCompleter(combolist, this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
obj->setCompleter(completer);
}
}

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


Название: Re: Кто как загружает QComboBox из БД
Отправлено: Пантер от Июль 29, 2009, 16:38
Можно создать модельку и прицепить ее к комбе. Так будет лучше.


Название: Re: Кто как загружает QComboBox из БД
Отправлено: CroCIV от Июль 30, 2009, 09:38
вместо QSqlQuery
юзай этот
QSqlQueryModel
даешь ему запрос, выполняешь
затем у QComboBox пользуешь эту чф void setModel ( QAbstractItemModel * model )
примерно так:
Код:
QSqlQueryModel *йцу(этот);
цйу->setQuery("запрос", подключениекбд);
QComboBox *ыва;
ыва->setModel(цйу);
ыва->setModelColumn ( int номеротображаемогостолбцамоделкиначинаяотнуля ) ;

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


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ecspertiza от Июль 30, 2009, 10:21
Хорошо а в чём преимущество загрузки через модель? По времени примерно одинаково, я потестил.


Название: Re: Кто как загружает QComboBox из БД
Отправлено: Пантер от Июль 30, 2009, 11:42
На каком объеме данных тестил?


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ecspertiza от Июль 30, 2009, 12:34
2220 записей. Ну так бы получается то первый метод быстрее то второй но в среднем одинаково.


Название: Re: Кто как загружает QComboBox из БД
Отправлено: CroCIV от Июль 30, 2009, 13:09
удобнее использовать модель, надежнее использовать модель, нагляднее использовать модель. Вопросы?


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ecspertiza от Июль 30, 2009, 14:43
Удобнее использовать модель тем что кода меньше? Некоем случаем это не наезд ну просто действительно интересно :)
В этом примере сразу и сортировка добавлена и tolTips-ы для каждого итема.

С наглядностью может где то даже согласен, а надежность в чем проявляется?


Название: Re: Кто как загружает QComboBox из БД
Отправлено: CroCIV от Июль 31, 2009, 13:06
Удобство:
 ну на сколько я знаю, одну и ту же модель можно подключить сразу к потенциально не ограниченному кол-ву компонент (умеющих работать с куте), не всегда, но иногда это очень удобно и "слегка" рациональнее расходуется память, и возможные изменения в модели отслеживать не надо (это я подозреваю)

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


Название: Re: Кто как загружает QComboBox из БД
Отправлено: CroCIV от Июль 31, 2009, 13:08
*умеющих работать с моделями, конечно же ;D


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ecspertiza от Июль 31, 2009, 13:23
Ну ладно с моделями разобрались, довольно хороший вариант, ну может есть ещё какие нибудь способы или алгоритмы для загрузки QComboBox.


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ildar от Сентябрь 29, 2009, 21:22
если загружать комбо из модели как получить соответствие "комбо индекс" <=> "id в таблице"?

например
Код:
QSqlQueryModel* model = ...;
model->setQuery("select id, title from ...");
QComboBox *combo = ...;
combo->setModel(model);
combo->setModelColumn (1) ;
combo->setModelKeyColumn(0); <---- что нибудь типа такого

ну или как вариант combo->setItemData ( int index, const QVariant & value, int role = Qt::UserRole ), но как сказать комбобоксу использовать id для Qt::UserRole?


Название: Re: Кто как загружает QComboBox из БД
Отправлено: lit-uriy от Сентябрь 29, 2009, 21:31
В общем случае Id в таблице может начинатся не с нуля и идти не попорядку. Поэтому простого сопоставления нет.


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ildar от Сентябрь 30, 2009, 08:36
а кто какие велосипеды использует?


Название: Re: Кто как загружает QComboBox из БД
Отправлено: CroCIV от Сентябрь 30, 2009, 08:50
Будем считать что я тут ниче не писал ))


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ildar от Сентябрь 30, 2009, 09:55
не совсем так, вернее совсем не так, index - это срока комбо, а не колонка модели

Код:
/*!
   Returns the data for the given \a role in the given \a index in the
   combobox, or QVariant::Invalid if there is no data for this role.
*/
QVariant QComboBox::itemData(int index, int role) const
{
    Q_D(const QComboBox);
    QModelIndex mi = d->model->index(index, d->modelColumn, d->root);
    return d->model->data(mi, role);
}

после загрузки комбо из базы нужны 2 операции:

1. после выбора пользователем итема комбо, надо получить id этого итема, и тут проблем нет, т.к. индекс комбо - это строка модели

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

model::match() - не подходит т.к. "By default, this function will perform a wrapping, string-based comparison on all items, searching for items that begin with the search term specified by value." т.е. если искать 1, он найдет 1, 10, 11 ...

остается либо делать самому цикл по модели и искать номер строки
либо использовать QSortFilterProxyModel для поиска а потом позвать mapToSource, но оба варианта кажутся мне жуткими костылями

не думаю что я первый кто столкнулся с подобной задачей,
поделитесь опытом плиз


Название: Re: Кто как загружает QComboBox из БД
Отправлено: CroCIV от Сентябрь 30, 2009, 11:02
Прошу меня простить, я недавно на C# ваял, дек это у меня от дотнетовского комбика в мозгу отложилось и наложилось.  ::)

Диктую ответ:
1. Если нужен индекс текущего элемента модели (например комбобокс используется в связке с таблвью), то достаточно выполнить следующее действие
комбобокс->setCurrentIndex ( таблвью->currentIndex().row() );

2. Если известен только id модели, то делаем так:
комбобокс->setCurrentIndex (модель->match(модель->index(i,j,QModelIndex()),Qt::DisplayRole,s,k,Qt::MatchExactly).first().row())

где i - номер строки для начала поиска (нам нада скорее всего 0 (тебе виднее)), j - номер столбца по которому будет осуществляться поиск (нам нада 0). s - эталон для поиска типа QVariant, k - предельное кол-во совпадений (нам нада 1, т.к. флаг Qt::MatchExactly заставит искать полное соответствие с эталоном + id скорее всего уникален иначе это не id :-) )

З.Ы.: пример работает только если match гарантированно вернет хотябы одно значение, иначе повалится с ошибкой, иначе там надо будет обьявалять переменную QModelIndexList и проверять ее на empty ()


Название: Re: Кто как загружает QComboBox из БД
Отправлено: ildar от Сентябрь 30, 2009, 11:08
да, enum Qt::MatchFlag я и упустил, обратил внимание только на дефолтные значения в match

спасиб  ;)