【问题标题】:How to update comboBox items when the database is being changed?更改数据库时如何更新组合框项目?
【发布时间】:2022-01-19 22:56:27
【问题描述】:

我用数据库中的项目填充组合框。当我尝试添加新项目、删除所有项目并再次添加它们时,如果正在更改 db,我会看到以下错误:

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();//function, that fills the comboBox
}

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());
        }
    }
}


void MainWindow::on_action_3_triggered()
{
    AddFood af(this);// in this new window a user writes what he wants to add
    af.setModal(true);
    af.exec();
    this->ui->comboBox->clear();
    this->ui->comboBox->addItem("test");
    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());
        }
}

如何使它工作而不是重复项目(如果我删除“this->ui->comboBox->clear();”会发生这种情况)?

【问题讨论】:

    标签: c++ sql sqlite qt debugging


    【解决方案1】:

    如果您多次致电foodListConstructor(),您将多次致电addDatabase()。根据documentation,这很好:

    使用驱动程序类型和连接名称 connectionName 将数据库添加到数据库连接列表中。 如果已经存在名为 connectionName 的数据库连接,则删除该连接。

    因此,您似乎只是看到 Qt 在内部输出调试消息。这不是一个真正的错误,所以请忽略它。虽然,一遍又一遍地添加相同的数据库是没有意义的。我建议只添加一次,然后在需要时使用QSqlDatabase::database() 访问它。

    QSqlQuery 错误是不言自明的。当查询不在活动记录上时,您尝试读取字段值。同样,这看起来像是另一个内部调试消息,而不是真正的错误。根据documentation

    如果字段索引不存在、查询处于非活动状态或查询位于无效记录上,则返回无效的QVariant

    为什么您会从非活动 SQL 记录中获得无效的 QVariant?那是我不能说的。你必须自己弄清楚。

    但它解释了最终的terminate 消息,这是一个真正的错误。您在 invalid QVariant 上调用 toString()

    在不受支持的变体上调用 QVariant::toString() 会返回一个空字符串。

    在此过程中,std::stoi() 被一个不代表整数值的字符串调用(即,可能是您添加到comboBox 的空字符串),因此它会引发std::invalid_argument 异常你没有捕捉到,它正在逃出你的应用程序的主函数,导致 C++ 运行时调用std::terminate() 以退出应用程序。

    std::stoi() 在哪里被调用?您需要为此搜索代码。你有连接到comboBox 的事件处理程序吗?

    话虽如此,请尝试更多类似的东西:

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("food_list.db");
        foodListConstructor();
    }
    
    void MainWindow::foodListConstructor()
    {
        ui->comboBox->clear();
    
        QSqlDatabase db = QSqlDatabase::database("QSQLITE");
        QSqlQuery query("SELECT food_name FROM food", db);
        while (query.next())
        {
             QVariant v = query.value(0);
             if (v.isValid())
                 ui->comboBox->addItem(v.toString());
        }
    }
    
    void MainWindow::on_action_3_triggered()
    {
        AddFood af(this);
        af.setModal(true);
        af.exec();
        foodListConstructor();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 2013-02-15
      • 2019-08-08
      相关资源
      最近更新 更多