I'm testing the code under QGIS3, but I fear that isinstance(item, item_class), in my case: isinstance(item, QgsLayoutItemPicture) returns always false because item is of QgsLayoutItem generic class
Nyall's workaround works for me without exceptions: from qgis.core import QgsProject, QgsLayoutItemPicture import sip myLayout = QgsProject.instance().layoutManager().layoutByName('test') myLayoutPicture = sip.cast(myLayout.itemById("picture"),QgsLayoutItemPicture) myLayoutPicture.setPicturePath("path to an image") 2018-01-24 10:20 GMT+01:00 Etienne Trimaille <etienne.trimai...@gmail.com>: > Is-it possible to remove this function from SIP bindings? According to SIP > version? > > It's a common issue, already raised on the mailing list and in plugin > issue trackers. > > I'm copy/pasting another message/snippet from Martin which works perfectly: > > Not sure if that is related, was just looking into code of a plugin we > use with QGIS 2.18 and there for getting composer items we have this > helper method: > > @staticmethod > def get_composition_item(comp, item_id, item_class): > for item in comp.items(): > if isinstance(item, item_class): > if item.id() == item_id: > return item > > And you would call it e.g.: > ver_label = self.get_composition_item(self.oview_compn, 'version', > QgsComposerLabel) > > Not sure if that is to work around the same problem as you have - I > didn't write that code. And to get composer map items, we use > composition.getComposerMapById(id) > > 2018-01-24 10:09 GMT+03:00 Nyall Dawson <nyall.daw...@gmail.com>: > >> On 23 January 2018 at 22:34, Enrico Ferreguti <enrico...@gmail.com> >> wrote: >> > I'm trying to programmatically set a QgsLayoutPicture content in >> QGIS3.0: >> > >> > 1) I create a new print composition and I name it 'test' >> > 2) I create a picture frame in the composition and I call it 'picture' >> > 3) I run the following code: >> > >> > from qgis.core import QgsProject >> > myLayout = QgsProject.instance().layoutManager().layoutByName('test') >> > myLayoutPicture = myLayout.itemById("picture") >> > myLayoutPicture.setPicturePath("path to an image") >> > >> > and I get the following Exception: >> > AttributeError: 'QgsLayoutItem' object has no attribute 'setPicturePath' >> > >> > If I inspect myLayoutPicture object I found it is a >> qgis._core.QgsLayoutItem >> > not a QgsLayoutPicture >> > >> > Is this a correct behaviour or is it an issue? How can I get the right >> > Layout object? >> >> This became an issue after a certain sip version. It affects QGIS 2.x >> also, and seems to be caused by sip being unable to automatically cast >> classes which use multiple inheritance (like QgsComposerItem, >> QgsLayoutItem). The consequence is that Python is only aware of the >> base class, not the actual item subclass. >> >> I can't find anyway to fix this properly. So I hack around by forcing >> sip to manually cast to the correct item type, e.g. by inserting two >> lines* which look like this: >> >> # screw you sip, I'll just manually cast >> real_item = sip.cast(item, QgsLayoutItemPicture) >> >> It's not pretty, but it works... >> >> Nyall >> >> * the first line is critical for the fix to work correctly >> _______________________________________________ >> QGIS-Developer mailing list >> QGIS-Developer@lists.osgeo.org >> List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer >> Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer >> > >
_______________________________________________ QGIS-Developer mailing list QGIS-Developer@lists.osgeo.org List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer