def copy(self):
        field_expression_widget = QgsFieldExpressionWidget()
        field_expression_widget.setLayer(
            self._qgsfieldexpressionwidget.layer())
        field_expression_widget.setField(
            self._qgsfieldexpressionwidget.currentText())

        color_btn_widget = QgsColorButton()
        color_btn_widget.setColor(self._qgscolorbutton.color())
        spinbox = QtGui.QSpinBox()
        spinbox.setValue(self._qspinbox.value())
        return PresetRow(field_expression_widget, color_btn_widget, spinbox)
class PresetRow():
    def __init__(self,
                 qgsfieldexpressionwidget=None,
                 qgscolorbutton=None,
                 qspinbox=None):
        self._qgsfieldexpressionwidget = qgsfieldexpressionwidget
        if qgsfieldexpressionwidget is None:
            self._qgsfieldexpressionwidget = QgsFieldExpressionWidget()
        self._qgscolorbutton = qgscolorbutton
        if qgscolorbutton is None:
            self._qgscolorbutton = QgsColorButton()
        self._qspinbox = qspinbox
        if qspinbox is None:
            self._qspinbox = QtGui.QSpinBox()
        self._last_feature = None

    def set_layer(self, layer_id):
        self._qgsfieldexpressionwidget.setLayer(layer_id)

    def __del__(self):
        self._qgsfieldexpressionwidget.deleteLater()
        self._qgsfieldexpressionwidget = None
        self._qgscolorbutton.deleteLater()
        self._qgscolorbutton = None
        self._qspinbox.deleteLater()
        self._qspinbox = None

    def __str__(self):
        return "{}-{}-{}".format(str(self._qgsfieldexpressionwidget),
                                 str(self._qgscolorbutton),
                                 str(self._qspinbox))

    def __repr__(self):
        return self.__str__()

    def asLst(self):
        return self._qgscolorbutton, self._qgsfieldexpressionwidget, self._qspinbox

    @property
    def qgsfieldexp(self):
        return self._qgsfieldexpressionwidget

    @property
    def exp_txt(self):
        return self._qgsfieldexpressionwidget.currentText()

    @property
    def qgscolorbutton(self):
        return self._qgscolorbutton

    @property
    def qspinbox(self):
        return self._qspinbox

    @property
    def lvl(self):
        return self._qspinbox.value()

    def copy(self):
        field_expression_widget = QgsFieldExpressionWidget()
        field_expression_widget.setLayer(
            self._qgsfieldexpressionwidget.layer())
        field_expression_widget.setField(
            self._qgsfieldexpressionwidget.currentText())

        color_btn_widget = QgsColorButton()
        color_btn_widget.setColor(self._qgscolorbutton.color())
        spinbox = QtGui.QSpinBox()
        spinbox.setValue(self._qspinbox.value())
        return PresetRow(field_expression_widget, color_btn_widget, spinbox)

    #===========================================================================
    #
    #===========================================================================
    def dump(self):
        exp = self._qgsfieldexpressionwidget.currentText()
        #color=self._qgscolorbutton.color().name()
        color = self._qgscolorbutton.color().rgba()
        idx = self._qspinbox.value()
        res = {"exp": exp, "color": color, "idx": idx}
        return json.dumps(res)

    #=======================================================================
    #
    #=======================================================================
    def load(self, str_dump):
        res = json.loads(str_dump)
        self._qgsfieldexpressionwidget.setField(res["exp"])
        #self._qgscolorbutton.color().setNamedColor(res["color"])
        qcolor = self._qgscolorbutton.color()
        qcolor.setRgba(res["color"])
        self._qgscolorbutton.setColor(qcolor)
        self._qspinbox.setValue(res["idx"])

    @property
    def exp(self):
        return QgsExpression(self._qgsfieldexpressionwidget.asExpression())

    @property
    def qcolor(self):
        return self._qgscolorbutton.color()

    @property
    def color_rgba(self):
        return self._qgscolorbutton.color().rgba()

    @property
    def color_hex(self):
        return self._qgscolorbutton.color().name()

    def setFeature(self, feature):
        self._last_feature = feature

    def execute(self, feature=None):
        if feature is not None:
            self.setFeature(feature)
        if self._last_feature is None: return None
        else: return self.exp.evaluate(self._last_feature)