On Sun, 21 Jul 2019 at 21:16, Áron Gergely <[email protected]> wrote:
> This actually works, for the 1st time when I open a project file with bad > layers. Then the 2nd time, QGIS always crashes. > It seems once I replaced the bad layer handler during project start, QGIS is > not able to open a subsequent new project properly. Couldn't you achieve the same result by setting your bad layer handler directly in initGui? ># TODO: after this, call the GUI file dialog as in the default bad layer >handler, to allow the user to fix ># any other broken layers... not sure how to do this The bad news is -- unfortunately you cannot. The inbuilt bad layer handler isn't exposed to Python in any way, and as soon as you set a new bad layer handler method the existing inbuilt one is completely deleted. I've been thinking about a similar situation recently, where a client's IT department is continually replacing network paths and moving things around (they do it roughly every 6 months, with no notice in advance. yep.) This breaks many many paths in their qgis projects, but the fix is actually super simple since we know what the network path used to be and what it is now. So what I've been pondering is whether we need a new hook to allow a "data source pre-processor" function to be specified, much in the same way that custom bad layer handlers would be. This would be called BEFORE resolving any raw paths, and would simply take an input data source string and return a processed version of it. (e.g. by replacing outdated network paths with their new equivalent). In this way it would be transparent to users -- the paths would be automatically updated, and then they'd only see the bad layer handler dialog IF an updated path still doesn't exist. Does this sound like what you're seeking? Nyall > > Here is my example in code: > > class MyBadLayerHandler(QgsProjectBadLayerHandler): > """ > This is a custom bad layer handler that would work as the default one, > except it would automatically fix > a specific layer that is broken. > """ > > def __init__(self, path): > QgsProjectBadLayerHandler.__init__(self) > self.validLayerPath = path > > def handleBadLayers(self, domNodes): > # Some logic to look for a specific DomNode to fix, oversimplified > here: > for dom in domNodes: > dataSource = self.dataSource(dom) > > if dataSource is 'the broken path to the layer I want to fix': > # set correct data source then force re-read > self.setDataSource(domNodes, self.validLayerPath) > QgsProject.instance().readLayer(dom) > > # TODO: after this, call the GUI file dialog as in the default bad > layer handler, to allow the user to fix > # any other broken layers... not sure how to do this > > > class MyPlugin: > """My plugin""" > > def __init__(self): > self.validPath = 'valid path to layer' > self.badLayerHandler = None > > def hackyAndUglyReplacer(self, i, n): > """ > This hacky ugly function is to replace the bad layer handler early > on, before any layers would be loaded. > it is meant to be connected to the `layerLoaded` signal of > `QgsProject` > """ > # do not run further if there were other layers loaded before (e.g. > the signal was emitted before) > if i != 0: > return > > if not self.badLayerHandler: > self.badLayerHandler = MyBadLayerHandler(self.validPath) > QgsProject.instance().setBadLayerHandler(self.badLayerHandler) > > def initGui(self): > # start-up code here... > > #connect to signal > QgsProject.instance().layerLoaded.connect(self.hackyAndUglyReplacer) > > def unload(self): > try: > QgsProject.instance().layerLoaded.disconnect() > except Exception: > pass > > > Does anyone know what am I doing wrong here? Have I missed something? > Why does QGIS crash every 2nd time? > > I would be happy to pass the bad layer handler a better way than with the > current signal above. But the other signals I found are emitted 'too late' > already. > Perhaps here I am also doing something wrong? > > I tried looking for help but the web barely has any trace of documentation on > this. > > I also tried to see how this is done in other plugins e.g. the > changeDataSource plugin, but the authors seem to have removed the code when > they ported the plugin to QGIS 3.x > (perhaps a bad sign) > > In general it seems to me this part was also overhauled in QGIS3 but there > aren't many leads to follow on what is the current way of using custom bad > layer handlers. > > Maybe if we could put the story together on how to do this correctly, I could > document it and put it on the web for others to refer to. > > Hope you are having / had a great Sunday! > > Best regards, > Aron > > _______________________________________________ > QGIS-Developer mailing list > [email protected] > List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer > Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer _______________________________________________ QGIS-Developer mailing list [email protected] List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
