2

I am quite new to both QGIS and Python. I have inherited a project that needs to be upgraded from using QGIS 2.0 DUFOUR to 3.8 Zanzibar.

The way it works is, there is a separate application written in asp.net. On one of the web pages there is a button called 'Digitize'.

  • When the user clicks this it saves a file with the details of the current record, onto the web server.

  • The user then opens QGIS via a shortcut on their desktop. The QGIS app is locked down with only minimal functionality.

  • When the project has finished loading, a plugin button becomes available on the toolbar. This button creates a new Vector Layer by connecting to a mssql database.

    • The vector layer name is based on dynamic values in the file on the server, so it changes each time.
    • The layer is also removed every time QGIS is started.
    • It displays the features/polygons that have already been added (if there are any).
  • The user clicks the pencil to begin editing.
  • The user draws a polygon.
  • The user clicks save.

  • The user is always prompted to enter an id which the record needs as a foreign key in the database. However, the user will never have access to this ID which is a long string e.g. '0000000001-0000000000000264100' that is hidden in the code.

I can get this value in the code from the server file (see sublayerref below). My problem is I cannot find a way to set this programmatically.

Does anybody know how to do this?

Here is the code so far, the best I can come up with at the moment is using the signal 'editingStarted', but I haven't found any success setting the value of 'ForeignKeyFieldId' field.

    {
    def feedback2():
    print("XXXFEEDBACK2 ACTIVATED:" + sublayerref)
    df = QgsDefaultValue('var("varsublayerref")', True)
    for field in vlayer.fields():
        print("LayerField:" + field.name())
        if field.name() == "ForeignKeyFieldId":
            field.setDefaultValueDefinition(df)
            print("Job done")
crs = QgsCoordinateReferenceSystem("EPSG:27700")
uri = QgsDataSourceUri()
uri.setConnection(servername, portnumber, databasename, logon, password)
uri.setDataSource( schemaname, tablename, geometryfieldname,  sublayerid + " = '" + sublayerref + "'" ) 
uri.setSrid("EPSG: 27700")
uri.setUseEstimatedMetadata(True)
uri.setWkbType(QgsWkbTypes.Polygon)
primaryKeyColumn = "RecordId"
uri.setKeyColumn(primaryKeyColumn)

symbol = QgsFillSymbol.createSimple({'line_style': 'dash', 'color': layercolour })
symbol.setOpacity(0.5)
vlayer = QgsVectorLayer()
vlayer.setCrs(crs)
vlayer.setCustomProperty("labeling", "pal")
vlayer.setCustomProperty("labeling/enabled", "true")
vlayer.setCustomProperty("labeling/isExpression", True)
vlayer.setCustomProperty("labeling/fontFamily", "Arial")
vlayer.setCustomProperty("labeling/fontSize", "10")
vlayer.setCustomProperty("labeling/fontWeight", "2")
vlayer.setCustomProperty("labeling/fontBold", True)
vlayer.setCustomProperty("labeling/placement", "1")
vlayer.setCustomProperty("labeling/fieldName", "'" + labelprefix + " ' || " + '"' + pkfieldname + '"')
vlayer.setOpacity(0.5)
vlayer.updateExtents()
vlayer = iface.addVectorLayer(uri.uri(), layername, 'mssql')
vlayer.renderer().setSymbol(symbol)
vlayer = iface.activeLayer()
vlayer.editingStarted.connect(feedback2) ##testcode
}
1

I have found a way myself that does what I need. I have created a function at the top of the code like this;

def setNewFeatureKey(featureAdded):
    layer = qgis.utils.iface.activeLayer()
    x =  1 ##This is the number one, it is the field index of foreign key we want to set here!
    y = sublayerref ##this variable is set in the main code e.g. ''
    z = None ##the original value of the field for rollback, but I know it will always be null 
    ret = layer.changeAttributeValue(featureAdded, x, y, z, True ) #the QgsVectorLayer signal that does the work
    print(y) #just for debugging

Then in the main code, I added a callback to the vector layer like this;

vlayer.editingStarted.connect(feedback2) ##testcode
vlayer.featureAdded.connect(setNewFeatureKey)   #<-- new line

The https://qgis.org/api/classQgsVectorLayer.html documentation lists a signal method called 'featureAdded' which works for this problem.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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