5

I am trying to apply a style to the output file of a script that I ́m running from the toolbox in QGIS 3.4.7. The last step is as described below.

 def processAlgorithm(self, parameters, context, feedback):
 if parameters['Input1'] is not None:
 source = self.parameterAsSource(parameters,'Input1',context)
 (sink, dest_id3) = self.parameterAsSink(parameters,'Output1',context,source.fields(),source.wkbType(),source.sourceCrs())
 total = 100.0 / source.featureCount() if source.featureCount() else 0
 features = source.getFeatures()
 for current, feature in enumerate(features):
 sink.addFeature(feature, QgsFeatureSink.FastInsert)
 feedback.setProgress(int(current * total))

After that, I would like to apply a fixed style to the output file so that it will be displayed on Layers with the applied style. I reached the lines below:

 self.source.loadNamedStyle(u"C:\\Users\\ct279359\\Desktop\\Styles\\Roads.qml")
 self.source.triggerRepaint() 

I got this error:

AttributeError: 'InOut' object has no attribute 'source'

I would like to know the correct way to call the output file created in the first part.

I did some research on the subject Here, Here, Here, Here, Here and Here.

All explain ways to invoke the QML file or how to change the style of a file that is already in the Layers section. I need next to this, to invoke the correct output file.

-------------------------------------------------------------
Full code here.

from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
 QgsFeatureSink,
 QgsProcessingException,
 QgsProcessingAlgorithm,
 QgsProcessingParameterVectorLayer,
 QgsProcessingParameterFeatureSink,
 QgsProcessingParameterRasterLayer,
 QgsProcessingParameterRasterDestination,
 QgsVectorLayer,
 QgsProject)
import processing
class InOut(QgsProcessingAlgorithm):
 def tr(self, string):
 return QCoreApplication.translate('Processing', string)
 def createInstance(self):
 return InOut()
 def name(self):
 return 'InOut2'
 def displayName(self):
 return self.tr('InOut2')
 def group(self):
 return self.tr('Auxiliares')
 def groupId(self):
 return 'auxiliares1'
 def initAlgorithm(self, config=None):
 self.addParameter(QgsProcessingParameterVectorLayer('Input1','Input1',optional=True, types=[QgsProcessing.TypeVector], defaultValue=None))
 self.addParameter(QgsProcessingParameterFeatureSink('Output1','Output1', type=QgsProcessing.TypeVectorAnyGeometry, createByDefault=True, defaultValue=None))
 def processAlgorithm(self, parameters, context, feedback):
 if parameters['Input1'] is not None:
 source = self.parameterAsSource(parameters,'Input1',context)
 (sink, dest_id3) = self.parameterAsSink(parameters,'Output1',context,source.fields(),source.wkbType(),source.sourceCrs())
 total = 100.0 / source.featureCount() if source.featureCount() else 0
 features = source.getFeatures()
 for current, feature in enumerate(features):
 sink.addFeature(feature, QgsFeatureSink.FastInsert)
 feedback.setProgress(int(current * total))
 self.source.loadNamedStyle(u"C:\\Users\\ct279359\\Desktop\\Styles\\Roads.qml")
 self.source.triggerRepaint()
 return results
asked Nov 18, 2019 at 13:09

1 Answer 1

1

You need to turn the layer into a QGIS vector layer when importing it:

 #define vector layer 
 vlayer = QgsVectorLayer('your_output_file', 'layer_name', "ogr")
 # add the layer to the registry
 QgsProject.instance().addMapLayer(vlayer)
 # load style
 vlayer.loadNamedStyle('path_to_qml.qml')
swiss_knight
11.3k9 gold badges57 silver badges140 bronze badges
answered Nov 18, 2019 at 17:10
9
  • 1
    Don't do that if your script is set to run in a background thread (which is the default). You'll get crashes and all kinds of unpredictable behaviour as a result. Commented Nov 18, 2019 at 22:04
  • @ndawson, could you explain what you mean? Interested to learn more about crashes that could occur. Never had a problem on my side when importing layers with styles. Commented Nov 18, 2019 at 22:43
  • 3
    There's a few issues: 1. QgsProject cannot be accessed from anything but the main thread 2. If you create a QgsVectorLayer (or ANY QObject derived class) from a background thread, the object belongs to that thread and should only be accessed from that thread. By transferring it to the project instance (which lives in the main thread) the results will be unpredictable at best (and crashy at worst). Commented Nov 19, 2019 at 1:47
  • I see. What would be the correct way to import a layer into qgis with a style without using the main thread? Commented Nov 19, 2019 at 2:45
  • @B-C B. Even with the ndawson's warning, it didn't work out. I edited the question and put in my full code, maybe I forgot to mention something important. Commented Nov 19, 2019 at 14:21

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.