3

I am using QGIS with the in-built Python console. I want to replace some values in a shapefile with some other values. But when I try to change the attribute values, I get an error about the data types (see the code below):

Error: AttributeError: 'QVariant' object has no attribute 'split'

However, I find no way to convert the QVariant to a String. If I run the code without the editing turned on, everything works fine, but the changes are not saved. How can I convert the QVariant to a string and are there ways around this issue?

shp_layer = QgsVectorLayer(shp_path, "", "ogr")

with edit(shp_layer):
    for feature in shp_layer.getFeatures():
        height_str_list = feature[height_list_field].split(":", 1)[1][:-1].split(",")  # some fancy string editing in here, but i swear it works
        if '...' in height_str_list:
            height_str_list.remove('...')
        height_flt_list = [float(i) for i in height_str_list]
        feature[height_field] = sum(height_flt_list)/len(height_flt_list)  # because QGIS pretends not to know mean()
        shp_layer.updateFeature(feature)
    shp_layer.setSubsetString("")

I also discovered if I say height_str_list = feature[height_list_field].value().split(....)

I get another error:

"AttributeError: 'str' object has no attribute 'value'"

2 Answers 2

4

A perfect comment from @Jochen Schwarze:

When I do a=QVariant(42), str(a) I get something like '<PyQt5.QtCore.QVariant object at 0x00000274E6B760B8>' and not '42'

because just with the str() you may not get the desired output.

>>> a = QVariant(42)
>>> str(a)
'<PyQt5.QtCore.QVariant object at 0x000001700D003BA0>'

As a workaround to that issue I may suggest this solution:

Using the value() method

>>> a = QVariant(42)
>>> str(a.value())
'42'
>>> type(str(a.value()))
<class 'str'>

If you know that you have a string inside of your QVariant class, you can additionally use convert(*int targetTypeId*)-method, 'targetTypeId' is possible to find here, in our case it is 10.

>>> a = QVariant(42)
>>> a.convert(10)
True
>>> a.value()
'42'
>>> type(a.value())
<class 'str'>
3

The solution is to use str() on the QVariant.

1
  • 1
    When I do a=QVariant(42), str(a) I get something like '<PyQt5.QtCore.QVariant object at 0x00000274E6B760B8>' and not '42' ... Commented Mar 9, 2021 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.