Пример #1
0
    def test_on_update(self):
        """Test live update"""

        layer = QgsVectorLayer("Point?field=age:int", "vl", "memory")
        # set default value for numbers to [1, {age}], it will depend on the field age and should update
        field = QgsField('numbers', QVariant.List, 'array')
        field.setEditorWidgetSetup(QgsEditorWidgetSetup('List', {}))
        layer.dataProvider().addAttributes([field])
        layer.updateFields()
        layer.setDefaultValueDefinition(1,
                                        QgsDefaultValue('array(1, age)', True))
        layer.setEditorWidgetSetup(1, QgsEditorWidgetSetup('List', {}))
        layer.startEditing()
        form = QgsAttributeForm(layer)
        feature = QgsFeature(layer.fields())
        form.setFeature(feature)
        form.setMode(QgsAttributeEditorContext.AddFeatureMode)
        form.changeAttribute('numbers', [12])
        form.changeAttribute('age', 1)
        self.assertEqual(form.currentFormFeature()['numbers'], [1, 1])
        form.changeAttribute('age', 7)
        self.assertEqual(form.currentFormFeature()['numbers'], [1, 7])
Пример #2
0
class AttributesDock(QgsDockWidget):
    layerChanged = pyqtSignal(QgsMapLayer)
    currentValueChanged = pyqtSignal(str, QVariant)

    def __init__(self, iface):
        QgsDockWidget.__init__(
            self,
            QCoreApplication.translate('AttributesDock', 'Quick Attribution'))
        self.iface = iface
        self.widget = QWidget()
        self.widget.setLayout(QGridLayout())
        self.widget.setContentsMargins(0, 0, 0, 0)
        self.layerComboBox = QgsMapLayerComboBox()
        self.layerComboBox.layerChanged.connect(self.setLayer)
        self.layerComboBox.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        self.layerTitleLabel = QLabel()
        self.widget.layout().addWidget(self.layerTitleLabel, 0, 0, 1, 1)
        self.widget.layout().addWidget(self.layerComboBox, 0, 1, 1, 1)
        self.formWidget = QWidget()
        self.formWidget.setLayout(QGridLayout())
        self.formWidget.setContentsMargins(0, 0, 0, 0)
        self.widget.layout().addWidget(self.formWidget, 1, 0, 1, 2)
        self.setWidget(self.widget)
        self.attributeForm = None
        self.layer = None
        self.feature = None

        self.layerComboBox.setFilters(QgsMapLayerProxyModel.WritableLayer
                                      | QgsMapLayerProxyModel.VectorLayer)

        QgsProject.instance().readProject.connect(self.onProjectRead)

    def setLayer(self, layer):
        if layer == self.layer:
            return
        if self.layer:
            try:
                self.layer.destroyed.disconnect(self.onLayerRemoved)
            except TypeError:
                # Do not care if it is not connected
                pass
        self.layer = layer
        if self.layer:
            self.layer.destroyed.connect(self.onLayerRemoved)
        self.layerComboBox.setLayer(layer)
        if self.attributeForm:
            try:
                self.attributeForm.deleteLater()
            except RuntimeError:
                # Sometimes the form has already been deleted, that's ok for us
                pass
        if self.layer is not None:
            context = QgsAttributeEditorContext()
            context.setVectorLayerTools(self.iface.vectorLayerTools())
            context.setFormMode(QgsAttributeEditorContext.StandaloneDialog)
            self.attributeForm = QgsAttributeForm(self.layer, QgsFeature(),
                                                  context)
            self.attributeForm.hideButtonBox()
            try:
                self.layer.updatedFields.disconnect(
                    self.attributeForm.onUpdatedFields)
            except TypeError:
                pass
            fields = self.layer.fields()
            self.feature = QgsFeature(fields)
            for idx in range(self.layer.fields().count()):
                self.feature.setAttribute(idx, self.layer.defaultValue(idx))
            self.feature.setValid(True)
            self.attributeForm.setFeature(self.feature)
            self.attributeForm.widgetValueChanged.connect(
                self.onAttributeChanged)
            self.formWidget.layout().addWidget(self.attributeForm)
            self.layerChanged.emit(self.layer)

    def onLayerRemoved(self):
        self.setLayer(None)

    def onAttributeChanged(self, attributeName, value, changed):
        idx = self.layer.fields().indexOf(attributeName)
        if value != 'NULL':
            defaultValue = QgsExpression.quotedValue(value)
        else:
            defaultValue = 'NULL'
        self.layer.blockSignals(True)
        self.layer.setDefaultValueDefinition(idx,
                                             QgsDefaultValue(defaultValue))
        self.layer.blockSignals(False)
        self.currentValueChanged.emit(attributeName, value)

    def onProjectRead(self, doc):
        title, isDefined = QgsProject.instance().readEntry(
            'quick_attribution', 'layercbxtitle')
        if isDefined:
            self.layerTitleLabel.setText(title)
        else:
            self.layerTitleLabel.setText(self.tr('Layer'))