My apologies for the off-the-record answer.
For me it seems you have found a bug :-)
I can reproduce your problem and did not find a solution/explanation for it...
Before ADDED INFORMATION
Strange, but I don't think it's a bug. In QGIS 2.4 I loaded a vector layer, applied a style by loading a .qml saved in QGIS 2.2, and there were no issues. I made a small change in the value map, saved it as a new .qml and loading it again went smoothly.
If you mention '... when I edit them', do you mean you select another color range from the dropdown menu? Because that's perfectly possible without losing your value-description settings. Just don't click 'Classify' because that will mess up your value map according to the classification mode you selected. But I guess you know all that...
Opening a .qml file in Notepad, you normally should see your value map at the top. Something like:
<ranges>
<range symbol="0" lower="0.000000" upper="12000.000000" label="No data"/>
<range symbol="1" lower="12000.000000" upper="16000.000000" label="12000 - 16000"/>
<range symbol="2" lower="16000.000000" upper="21000.000000" label="16000 - 21000"/>
<range symbol="3" lower="21000.000000" upper="25000.000000" label="21000 - 25000"/>
<range symbol="4" lower="25000.000000" upper="29000.000000" label="25000 - 29000"/>
</ranges>
After your comment, this will probably help you further.
IF I understand what you're doing, you try to edit the values map under the Fields tab, and there you find a column called 'Edit Widget'.
I did not dig out that functionality yet, but assuming you just want to apply a style on a vector layer (nice colors and dito labels), open the Properties window of the vector layer you like to apply a style on, and do as follows.
- If you already have a .qml file, you can load it through 'Load Style ...' (A).
Check out that the name of the attribute/field (stored in the .qml file) corresponds with an existing attribute in the table of your vector layer. If not, just select from the dropdown menu the column/field/attribute you like to show in your map with your style (B). In the .qml file, you can find the attribute's name in the 3th line:
<renderer-v2 attr="FIELD_OF_INTEREST" symbollevels="1" type="graduatedSymbol">
If you're still happy with the style you loaded, fine! If not, edit the number of classes, choose a color ramp and a classification mode. If you're not satisfied with the lower and upper values of the generated classes, double-click in the area depicted with the red rectangle (C).
- A small window opens allowing you to adapt the lower and upper values to your wishes (D).
- Finally, you can edit the description of your classes (E). In this example you see the value map of a numerical field, but in case of, for example, a land use map, your value can be an integer code and the description the name of the corresponding land use.
- Click 'OK' to apply the configured style (maybe you can save your style first with 'Save Style').
All done, you'll notice that the applied changes (color and value map) will appear as a legend.
I'll answer the concrete question of copying/pasting layer styles with PyQGIS:
Select the source layer in the QGIS layer tree either by hand or by code.
Run the following command to copy the style:
iface.actionCopyLayerStyle().trigger()
Select another layer either by hand or by code (as you mentioned, it could be a layer in another QGIS window).
Run the following command to paste the style:
iface.actionPasteLayerStyle().trigger()
In general, some QGIS functionality is exposed through iface
object. Have a look at the different actions that you could call (trigger) at http://www.qgis.org/api/classQgisInterface.html
For your specific use case, since you seem to be managing the clipboard, I suggest you to do this:
- Save the layer style into a temporary QML file (using
layer.saveNamedStyle( pathToQMLFile )
),
- Copy the path to that file into the clipboard,
- When pasting, load the style from the QML file path in the clipboard (using
layer.loadNamedStyle( pathToQMLFile )
and then layer.triggerRepaint()
).
Best Answer
I suggest you to do what I state in 1. and choose whether you want to go for 2. while the problem is fixed in QGIS.
Indeed, there is a problem with those functions, so you can inform QGIS devs about the issue you found by posting in the QGIS-dev mailing list and/or reporting it in the QGIS bug tracker (see Filing an issue).
Implement a workaround.
Since
layer.styleURI()
is not giving you the updated style, you can use your own functions for keeping track of your styles. For instance, by implementing the following functions, you could get updated styles by callingstyleURI( layer )
andloadNamedStyle( layer, stylePath )
.Just define the functions this way:
Once they are defined, you could use them this way:
Since I've used custom properties in these functions, the style path will be saved across sessions just by saving your QGIS project.
You could even write the function definitions in a .py file (say
style_functions.py
) and save it in the same folder as your QGIS project. This way, you would just need to write:in the QGIS Python console to have the functions ready to be used.