Название: Combobox и БД Отправлено: Nabokov от Июнь 06, 2020, 17:39 Доброго времени суток, уважаемые форумчане. Qt начал заниматься недавно. Разрабатываю приложение для ведения расходов.
В моем приложении используется БД SQLITE. В ней есть следующая таблица: (http://images.vfl.ru/ii/1591453847/37519a96/30734986_m.png) (http://vfl.ru/fotos/37519a9630734986.html) Это Названия категорий расходов. Id - внешний ключ. На графическом интерфейсе у меня есть Combobox. В него я заношу имена категорий таким образом: 1) Создаю объект QSqlQuery и выполняю запрос в БД на выборку всех имен продуктов. 2) Далее с помощью addItem добавляю это в Combobox. Далее, в некотором месте программы я хочу получить Id категории в соответствии с тем, что в данный момент выбрано в combobox'е. И вот тут из-за того, что в Qt я новичок, я не совсем понимаю, как грамотно это сделать. В голову приходят следующие идеи: 1) Выполнять SQL-запрос на поиск Id категории по ее имени. 2) Либо где-то в таблице хранить map<Name,Id>. И в нужный момент получить нужный Id по имени. Очевидно, что оба эти подхода плохие, хочется какого-то более элегантного решения. Т.е., грубо говоря, чтобы я мог написать ui->combobox->currentText() и получить не имя категории, а именно ее Id. Надеюсь на вашу помощь. Название: Re: Combobox и БД Отправлено: Nabokov от Июнь 06, 2020, 19:29 После поисков ответов в интернете наткнулся вот на что:
Вроде бы в таких ситуациях, когда надо в комбобоксе отображать данные из БД, используют QSqlQueryModel (как вариант). Я реализовал следующий код: Код: model = new QSqlQueryModel(); Код: ui->chooseCategory->setModelColumn(0); Название: Re: Combobox и БД Отправлено: demal от Июнь 06, 2020, 21:54 это подключение QComboBox к БД
model=new QSqlTableModel; model->setTable("lichdel"); model->setSort(2,Qt::AscendingOrder); ui->Fam->setModel(model); ui->Fam->setModelColumn(2); А это получение значение другого столбца ui->Nam->setText(model->record(ui->Fam->currentIndex()).value(3).toString()); Название: Re: Combobox и БД Отправлено: tamplier от Июнь 07, 2020, 07:34 Доброго времени суток, уважаемые форумчане. Qt начал заниматься недавно. Разрабатываю приложение для ведения расходов. В моем приложении используется БД SQLITE. В ней есть следующая таблица: (http://images.vfl.ru/ii/1591453847/37519a96/30734986_m.png) (http://vfl.ru/fotos/37519a9630734986.html) Это Названия категорий расходов. Id - внешний ключ. На графическом интерфейсе у меня есть Combobox. В него я заношу имена категорий таким образом: 1) Создаю объект QSqlQuery и выполняю запрос в БД на выборку всех имен продуктов. 2) Далее с помощью addItem добавляю это в Combobox. Далее, в некотором месте программы я хочу получить Id категории в соответствии с тем, что в данный момент выбрано в combobox'е. И вот тут из-за того, что в Qt я новичок, я не совсем понимаю, как грамотно это сделать. В голову приходят следующие идеи: 1) Выполнять SQL-запрос на поиск Id категории по ее имени. 2) Либо где-то в таблице хранить map<Name,Id>. И в нужный момент получить нужный Id по имени. Очевидно, что оба эти подхода плохие, хочется какого-то более элегантного решения. Т.е., грубо говоря, чтобы я мог написать ui->combobox->currentText() и получить не имя категории, а именно ее Id. Надеюсь на вашу помощь. Постоянно выполнять из программы SQL-запросы, это не очень хорошая идея, тем более всё можно реализовать только средствами Qt (выполнив прежде один запрос к БД). Я бы работал не с моделью в данном случае (если база небольшая) а с QSqlQuery. Выполняешь запрос с необходимыми для задачи полями, "помещаешь" его в объект QSqlQuery. Метод next() для итерирования (прохода) по всем строкам запроса и методы: value(int), value(const QString &), для выбора нужного поля в таблице БД. Результат запроса можно поместить в QMultiHash, например (на случай совпадений в базе значений поля Name). И далее работать с хэш-таблицей... Название: Re: Combobox и БД Отправлено: tamplier от Июнь 07, 2020, 08:23 Со старого проекта дернул подключение к БД и накидал вариант решения задачи с использованием QMultiHash ("Multi" на случай, если значения поля Name в таблице повторяются).
С помощью QtDesigner создал виджет и "кинул" на него QComboBox и QPushButton. widget.h: Код
widget.cpp: Код
main.cpp: Код
Нужный результат выдается в слоте on_pushButton_clicked() при сигнале clicked() кнопки pushButton. Код
P.S.: Единственное не сделал проверку на повторяющиеся значения. Надо будет использовать метод QHash::values(), который возвращают QList(). И уже с этим списком работать... В данном случае будет возвращено только одно значение Id (последнее в QMultiHash). Если точно повторений в таблице нет, то достаточно метода QHash::value(). И совет от новичка в Qt новичку: старайся почаще заглядывать в справку, сначала будет сложно разобраться, придется все-равно часто обращаться к интернету, но со временем станет легче разбираться с материалом и это скажется на быстроте кодинга и эффективности. И не забывай смотреть методы родителей класса, там много интересного :) И еще, советую простые окна (формы) создавать вручную (без QtDesigner) так зачастую проще и меньше лишнего кода. Наследуешься от QWidget, создаешь нужные элементы управления, создаешь нужный Layout, добавляешь в него эти элементы управления и устанавливаешь Layout на данный виджет. Название: Re: Combobox и БД Отправлено: Nabokov от Июнь 07, 2020, 11:58 ui->Nam->setText(model->record(ui->Fam->currentIndex()).value(3).toString()); То что нужно, спасибо)Название: Re: Combobox и БД Отправлено: Nabokov от Июнь 07, 2020, 12:04 Со старого проекта дернул подключение к БД и накидал вариант решения задачи с использованием QMultiHash ("Multi" на случай, если значения поля Name в таблице повторяются). Спасибо за помощь, но мне все-таки не нравится вариант с хранением пары <QString, int> в каком-либо контейнере. Это требует написания лишнего кода, например, как вы уже отметили, в случае, если значения могут повторяться.С помощью QtDesigner создал виджет и "кинул" на него QComboBox и QPushButton. P.S.: Единственное не сделал проверку на повторяющиеся значения. Надо будет использовать метод QHash::values(), который возвращают QList(). И уже с этим списком работать... В данном случае будет возвращено только одно значение Id (последнее в QMultiHash). Если точно повторений в таблице нет, то достаточно метода QHash::value(). И совет от новичка в Qt новичку: старайся почаще заглядывать в справку, сначала будет сложно разобраться, придется все-равно часто обращаться к интернету, но со временем станет легче разбираться с материалом и это скажется на быстроте кодинга и эффективности. И не забывай смотреть методы родителей класса, там много интересного :) И еще, советую простые окна (формы) создавать вручную (без QtDesigner) так зачастую проще и меньше лишнего кода. Наследуешься от QWidget, создаешь нужные элементы управления, создаешь нужный Layout, добавляешь в него эти элементы управления и устанавливаешь Layout на данный виджет. Я воспользовался вариантом, который написал demal: Код: model = new QSqlQueryModel(); Название: Re: Combobox и БД Отправлено: Пантер от Июнь 07, 2020, 12:19 Модель кеширует данные сама и не лезет в БД каждый раз.
Название: Re: Combobox и БД Отправлено: Nabokov от Июнь 07, 2020, 13:20 Модель кеширует данные сама и не лезет в БД каждый раз. Простите, не очень понимаю, на что вы намекаете. Типо можно вообще setQuery не делать?Название: Re: Combobox и БД Отправлено: Пантер от Июнь 07, 2020, 13:49 QSqlQueryModel кеширует данные внути себя. То есть, хранит локально данные и запрашивает из из БД только один раз. На сколько я помню.
Название: Re: Combobox и БД Отправлено: tamplier от Июнь 07, 2020, 14:20 Со старого проекта дернул подключение к БД и накидал вариант решения задачи с использованием QMultiHash ("Multi" на случай, если значения поля Name в таблице повторяются). Спасибо за помощь, но мне все-таки не нравится вариант с хранением пары <QString, int> в каком-либо контейнере. Это требует написания лишнего кода, например, как вы уже отметили, в случае, если значения могут повторяться.С помощью QtDesigner создал виджет и "кинул" на него QComboBox и QPushButton. P.S.: Единственное не сделал проверку на повторяющиеся значения. Надо будет использовать метод QHash::values(), который возвращают QList(). И уже с этим списком работать... В данном случае будет возвращено только одно значение Id (последнее в QMultiHash). Если точно повторений в таблице нет, то достаточно метода QHash::value(). И совет от новичка в Qt новичку: старайся почаще заглядывать в справку, сначала будет сложно разобраться, придется все-равно часто обращаться к интернету, но со временем станет легче разбираться с материалом и это скажется на быстроте кодинга и эффективности. И не забывай смотреть методы родителей класса, там много интересного :) И еще, советую простые окна (формы) создавать вручную (без QtDesigner) так зачастую проще и меньше лишнего кода. Наследуешься от QWidget, создаешь нужные элементы управления, создаешь нужный Layout, добавляешь в него эти элементы управления и устанавливаешь Layout на данный виджет. Я воспользовался вариантом, который написал demal: Код: model = new QSqlQueryModel(); Пожалуйста. Если вариант demal подходит больше и код меньше, то он лучший. Просто, как правило, технология "модель - представление" используется для "больших" данных, а в вашем случае, как я понял, их немного (раз помещаете результат запроса в QComboBox). Но самое главное чтобы код корректно и быстро работал, и был достаточно лаконичен :) |