Как обновить содержимое 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 шт):

Автор решения: Sergey Tatarincev

Английским по белому написано что вы пытаетесь реюзать соединение. 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");
    ...
}
→ Ссылка