TLDR: When running the code inside a separate class, make your layer objects instance attributes (members of self).
I made a few tests to try and reproduce your issue. The results of these are summarized below.
The following simple, procedural code block works works fine when run from the Python console (using one of my own vector layers to test):
dlg = QDialog()
map_scene = QgsMapCanvas(dlg)
layout = QVBoxLayout(dlg)
layout.addWidget(map_scene)
dlg.setLayout(layout)
fiberlayer = QgsProject().instance().mapLayersByName("AUS_roads")[0]
if fiberlayer.selectedFeatureCount() > 0:
vlayer = fiberlayer.materialize(QgsFeatureRequest().setFilterFids(
fiberlayer.selectedFeatureIds()))
vlayer.renderer().symbol().setWidth(1)
vlayer.renderer().symbol().setColor(QColor("blue"))
print(vlayer.isValid())# its true
map_scene.setDestinationCrs(fiberlayer.crs())
rasterLyr = QgsRasterLayer("type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png",
"Open Street Map",
"wms")
print(rasterLyr.isValid()) #raster also valid
map_scene.setLayers([vlayer, rasterLyr])
map_scene.setExtent(vlayer.extent(), True)
map_scene.refreshAllLayers()
dlg.setGeometry(250, 250, 700, 500)
dlg.show()
Not knowing exactly how your plugin is structured, I tried the following where a QgsMapCanvas
object is created in a class which inherits from QDialog
, and is instantiated inside another class which is in turn instantiated inside a running QGIS instance. In this example, the vector and raster objects are not created as instance attributes with the self keyword (as is shown in your question). The result is that the dialog is shown but the layers are not displayed on the canvas.
class testClass():
def __init__(self):
self.dlg = myDialog()
self.fiberlayer = QgsProject().instance().mapLayersByName("AUS_roads")[0]
if self.fiberlayer.selectedFeatureCount() > 0:
vlayer = self.fiberlayer.materialize(QgsFeatureRequest().setFilterFids(
self.fiberlayer.selectedFeatureIds()))
vlayer.renderer().symbol().setWidth(1)
vlayer.renderer().symbol().setColor(QColor("blue"))
print(vlayer.isValid())# its true
self.dlg.map_scene.setDestinationCrs(self.fiberlayer.crs())
rasterLyr = QgsRasterLayer("type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png",
"Open Street Map",
"wms")
print(rasterLyr.isValid()) #raster also valid
self.dlg.map_scene.setLayers([vlayer, rasterLyr])
self.dlg.map_scene.setExtent(vlayer.extent(), True)
self.dlg.map_scene.refreshAllLayers()
self.dlg.show()
class myDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
self.setGeometry(250, 250, 700, 500)
self.map_scene = QgsMapCanvas(self)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.map_scene)
self.setLayout(self.layout)
t = testClass()
Result:

I found that by simply making the layer objects instance attributes with the self keyword, solved the problem e.g.
self.vlayer = self.fiberlayer.materialize(QgsFeatureRequest().setFilterFids(
self.fiberlayer.selectedFeatureIds()))
self.rasterLyr = QgsRasterLayer("type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png",
"Open Street Map",
"wms")
self.dlg.map_scene.setLayers([self.vlayer, self.rasterLyr])
Interestingly enough, I also found that simply adding the layer objects to an instance attribute list, then passing that list to the setLayers() method also worked fine.
See below for working code snippet and result. Just replace with your own vector layer name to test.
class testClass():
def __init__(self):
self.dlg = myDialog()
self.fiberlayer = QgsProject().instance().mapLayersByName("AUS_roads")[0]
self.layers = list()
if self.fiberlayer.selectedFeatureCount() > 0:
vlayer = self.fiberlayer.materialize(QgsFeatureRequest().setFilterFids(
self.fiberlayer.selectedFeatureIds()))
vlayer.renderer().symbol().setWidth(1)
vlayer.renderer().symbol().setColor(QColor("blue"))
print(vlayer.isValid())# its true
self.dlg.map_scene.setDestinationCrs(self.fiberlayer.crs())
rasterLyr = QgsRasterLayer("type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png",
"Open Street Map",
"wms")
print(rasterLyr.isValid()) #raster also valid
self.layers.extend([vlayer, rasterLyr])
self.dlg.map_scene.setLayers(self.layers)
self.dlg.map_scene.setExtent(vlayer.extent(), True)
self.dlg.map_scene.refreshAllLayers()
self.dlg.show()
class myDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
self.setGeometry(250, 250, 700, 500)
self.map_scene = QgsMapCanvas(self)
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.map_scene)
self.setLayout(self.layout)
t = testClass()
Result:
