2

I want to have this add from the file or select layer in my plugin widget like:

enter image description here

I think it can be done with some combination of QgsFileWidget and QgsMapLayerComboBox yet one just selects a file path into text input while another only selects existing layers.

So How to add or select a layer in QGIS standalone plugin (inside any QDialog) (like they do it in QgsProcessingAlgorithm)?

2

Processing algorithm dialogs use widget wrappers for different parameters such as QgsProcessingMapLayerComboBox, which is what you are referring to. I don't know of a similar generic out-of-the-box 'map layer/ file selection combination widget' which you can use in standard, non-processing Python plugins. I may be wrong here, but I think you will have to implement your own solution by writing a basic kind of widget wrapper. I present a simple example below, for vector layers, which should give you an idea of how this would work and how you could use this idea in a plugin.

from pathlib import Path

class InputLayerFileWidget(QWidget):
    def __init__(self, parent=None):
        self.parent = parent
        QWidget.__init__(self)
        self.v_layout = QVBoxLayout()
        self.lbl = QLabel('Input layer:')
        self.selection_widget = QWidget()
        self.h_layout = QHBoxLayout()
        self.mlcb = QgsMapLayerComboBox(self.selection_widget)
        self.mlcb.setFilters(QgsMapLayerProxyModel.VectorLayer)
        self.file_selection_button = QPushButton("\u2026", self.selection_widget)
        self.file_selection_button.setMaximumWidth(30)
        self.file_selection_button.setToolTip('Select from file')
        for c in self.selection_widget.children():
            self.h_layout.addWidget(c)
        self.selection_widget.setLayout(self.h_layout)
        self.v_layout.addWidget(self.lbl)
        self.v_layout.addWidget(self.selection_widget)
        self.setLayout(self.v_layout)
        
        self.file_selection_button.clicked.connect(self.getFile)
        
    def getFile(self):
        file_name = QFileDialog.getOpenFileName(None, 'Select file', '', filter='*.shp; *.gpkg; *.tab')
        if file_name:
            self.mlcb.setAdditionalItems([file_name[0]])
            self.mlcb.setCurrentIndex(self.mlcb.model().rowCount()-1)
                
    def currentLayer(self):
        layer = self.mlcb.currentLayer()
        if layer is not None:
            return layer
        else:
            path = self.mlcb.currentText()
            name = Path(path).stem
            layer = QgsVectorLayer(path, name, 'ogr')
            if layer.isValid():
                return layer
        return None

class MainDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.layout = QVBoxLayout()
        self.input_layer_widget = InputLayerFileWidget(self)
        self.lbl = QLabel('Layer object info...', self)
        self.btn = QPushButton('Get Input Layer', self)
        self.layout.addWidget(self.input_layer_widget)
        for _widget in self.children():
            self.layout.addWidget(_widget)
        self.setLayout(self.layout)
        self.setGeometry(200, 200, 1000, 250)
        
        self.btn.clicked.connect(self.get_input_layer)
    
    def get_input_layer(self):
        self.lbl.setText(str(self.input_layer_widget.currentLayer()))
        
        
w = MainDialog()
w.show()

Demonstration screencast of resulting functionality:

enter image description here

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.