Как обновить содержимое comboBox, который заполняется из базы данных, при изменении самой бд?
Первый раз заполняю - всё норм, потом, когда пытаюсь перезаполнить после обновления бд, прога вылетает
Делаю калькулятор калорий в qt creator, в comboBox добавляю элементы, которые беру из базы данных. Если пользователь добавляет что-то в бд, то оно должно после этого добавляться и в comboBox, для этого я стёрла всё из последнего и решила повторить запрос, который делала в конструкторе. Получила ошибку/ошибки
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed. QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed. QSqlQuery::value: not positioned on a valid record created terminate called after throwing an instance of 'std::invalid_argument' what(): stoi 21:41:04: Debugging of C:\Users\79107\Downloads\build-food_calculator-Desktop_Qt_6_2_2_MinGW_64_bit-Debug\debug\food_calculator.exe has finished with exit code 3.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
MainWindow::foodListConstructor();//вынесла в отдельную функцию первое заполнение комбобокса, но потом, когда заметила, что всё не работает, стало так, как тут
}
void MainWindow::foodListConstructor()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("food_list.db");
db.open();
QSqlQuery query("SELECT food_name FROM food", db);
if(query.isActive())
{
while(query.next())
{
ui->comboBox->addItem(query.value(0).toString());
}
}
//db.close();
}
void MainWindow::on_action_3_triggered()
{
AddFood af(this);//вызываю окно, в котором пользователь вводит, что добавить в бд
af.setModal(true);
af.exec();
this->ui->comboBox->clear();
this->ui->comboBox->addItem("проба");
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("food_list.db");
db.open();
QSqlQuery query1("SELECT food_name FROM food", db);
if(query1.isActive())
{
while(query1.next())
{
ui->comboBox->addItem(query1.value(0).toString());
}
}
//foodListConstructor();
}
Хотелось бы сделать так чтобы в комбобоксе не появлялось дважды всё, что было в базе, т.е. в него добавлялось то, что добавил пользователь в базу, но не копировались уже существующие элементы
Ответы (1 шт):
Английским по белому написано что вы пытаетесь реюзать соединение. db.close() только закрывает соединение, но оставляет его в списке. Чтобы убрать соединение из списка соединений, используйте QSqlDatabase::removeDatabase()
Работать будет, однако добавлю, что такой подход корявый - к чему каждый раз пересоздавать соединение с БД? Если предполагается, что БД может использоваться другими программами во время работы вашей, то достаточно будет закрывать соединение:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
...
db = QSqlDatabase::addDatabase("QSQLITE"); //db объявить в классе
db.setDatabaseName("food_list.db");
}
void MainWindow::foodListConstructor()
{
db.open();
QSqlQuery query("SELECT food_name FROM food");
...
db.close();
}
void MainWindow::on_action_3_triggered()
{
db.open();
QSqlQuery query("SELECT food_name FROM food");
...
db.close();
}
Но sqlite в принципе не очень подходит для множественных подключений, и если они не используются (что скорее всего так), то лучше делать сразу по человечески
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
...
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("food_list.db");
db.open();
}
void MainWindow::foodListConstructor()
{
QSqlQuery query("SELECT food_name FROM food");
...
}
void MainWindow::on_action_3_triggered()
{
QSqlQuery query("SELECT food_name FROM food");
...
}