为啥我不能更改 QMap 中的 Qvariant 值?

Posted

技术标签:

【中文标题】为啥我不能更改 QMap 中的 Qvariant 值?【英文标题】:Why can't I change the Qvariant value inside a QMap?为什么我不能更改 QMap 中的 Qvariant 值? 【发布时间】:2021-09-30 17:41:54 【问题描述】:

我正在尝试传递一个名为QMap<QString, QVariant>* collect_row 的对象,然后我将用QVariant 值填充second 元素。 second 元素中的当前值为0

我正在使用此代码连接到数据库,然后将数据库中的行复制到QMap<QString, QVariant>* collect_row

DATABASE_STATUS Database::get_row_from(const QString& table_name, const QString& at_column_name, const QString& where_value_is_equal_to, QMap<QString, QVariant>* collect_row)
    /* Check if we are connected */
    if(!getInstance()->qSqlDatabase.isOpen())
        return DATABASE_STATUS_NOT_CONNECTED;

    QSqlQueryModel qSqlQueryModel;
    qSqlQueryModel.setQuery("SELECT * FROM " + table_name + " WHERE " + at_column_name + " = '" + where_value_is_equal_to + "'");
    QSqlRecord record = qSqlQueryModel.record(0);
    QList<QString> column_names = collect_row->keys();
    QList<QVariant> values_holders = collect_row->values();
    for(int i = 0; i < column_names.length(); i++)
        QVariant value_holder = values_holders.at(i);
        value_holder.setValue(record.value(record.indexOf(column_names.at(i))));
    

    return DATABASE_STATUS_OK;

所以这里我有column_names,我想将QVariant 值设置为values_holders

for(int i = 0; i < column_names.length(); i++)
    QVariant value_holder = values_holders.at(i);
    value_holder.setValue(record.value(record.indexOf(column_names.at(i))));

我想改写这段代码,但我不能写values_holders.at(i).setValue(),因为那个函数不存在。

for(int i = 0; i < column_names.length(); i++)
    values_holders.at(i).setValue(record.value(record.indexOf(column_names.at(i))));

database.cpp:72:30: error: no matching member function for call to 'setValue'
qvariant.h:560:23: note: candidate function template not viable: 'this' argument has type 'const QVariant', but method is not marked const

这意味着我无法更改元素,即使有一个名为 .setValue 的函数?

【问题讨论】:

我有一段时间没有使用 Qt,但我想知道 QList&lt;QVariant&gt; values_holders = collect_row-&gt;values();QVariant value_holder = values_holders.at(i); 之类的东西是否分别从地图和列表中复制值,而您正在修改这些副本地图中的对象。 @RetiredNinja 所以你的意思是他们没有共享相同的内存? 您可能具有 Java 或 C# 背景。但这是 C++。 C++ 具有值语义,而不是引用语义。你必须学会​​使用参考。我猜这需要你一段时间。将思维模式从引用语义完全转换为价值语义非常困难。 IIRC Qt 是 Copy-on-Write,因为 Qt 早于 C++11。 Qt detach & 容器语义总是让我头疼。 【参考方案1】:

使用此代码。请注意,我将QMap 指针更改为引用。我相信代码应该可以工作,尽管我还没有测试过。但它仍然非常丑陋且非常不理想。但我试图对您提供的代码进行最小的更改。

DATABASE_STATUS Database::get_row_from(const QString& table_name, const QString& at_column_name, const QString& where_value_is_equal_to, QMap<QString, QVariant>& collect_row)

    /* Check if we are connected */
    if(!getInstance()->qSqlDatabase.isOpen())
        return DATABASE_STATUS_NOT_CONNECTED;

    QSqlQueryModel qSqlQueryModel;
    qSqlQueryModel.setQuery("SELECT * FROM " + table_name + " WHERE " + at_column_name + " = '" + where_value_is_equal_to + "'");
    QSqlRecord record = qSqlQueryModel.record(0);
    QList<QString> column_names = collect_row.keys();
    for(int i = 0; i < column_names.length(); i++)
        QString column_name = column_names.at(i);
        collect_row[column_name] = record.value(record.indexOf(column_name));
    

    return DATABASE_STATUS_OK;

【讨论】:

以上是关于为啥我不能更改 QMap 中的 Qvariant 值?的主要内容,如果未能解决你的问题,请参考以下文章

Qt DBus 属性转换为地图

如何更改 QListView 中项目的颜色

当 QDataStream 没有这种方法时,为啥可以将 QVariant 写入 QDataStream?

为啥我不能更改实例化后用作属性的结构中的字段?

为啥我不能从不同命名空间中的朋友类更改类的私有成员?

为啥我不能通过取消选中 CodeIgniter 中的复选框来更改数据库中的数据?