Exemple #1
0
class ModelJson(QObjectListModel):
    def __init__(self, objname, parent=None):
        QObjectListModel.__init__(self, parent)
        self.setObjectName(str(objname))
        self.m_locale = QLocale("es")  #temp, auto changue when login
        #self.m_proxy = ProxyModelJson()
        self.m_order = ""
        self.boolMetadata = False
        self.m_fields = QJsonArray()  #[]#QJsonArray
        self.m_fieldsPoint = []  #5.2up
        self.m_maxLimit = 100
        self.m_domain = QJsonArray()  #[]#QJsonArray
        self.m_orderTryton = QJsonArray()  #[]#QJsonArray
        self.m_preferences = {}
        self.m_qjsonnetwork = QJsonNetwork()
        self.m_fieldsFormatDecimal = []  #QJsonArray
        self.m_fieldsFormatDateTime = []  #QJsonArray
        self.m_model_method_search = ""
        self.m_hasIndexOfId = {}
        self.m_engine = None  #QQmlApplicationEngine()
        self.autoBusy = True
        self.boolSynchro = True  # add synchronous call (calldirect), best performance!

    def prepareDeletion(self):
        if self.boolSynchro == False:
            self.m_qjsonnetwork.signalResponse.disconnect(self.slotJsonConnect)
        self.setFields(QJsonArray())
        self.clear()

    @Slot(int, result=int)
    def indexisOfId(self,
                    mid):  #el index del record en el modelo, no en el proxy
        return self.m_hasIndexOfId.get(mid, -1)

    @Slot(bool)
    def activateMetadata(self, meta):
        self.boolMetadata = meta

    @Slot("QJsonObject")
    def setPreferences(self, preferences):
        self.m_preferences = preferences

    @Slot(str)
    def setOrderInternal(
            self, order
    ):  # only proxy, defaul false, no es necesario con order tryton
        self.m_order = order
        if self.m_order != "":
            self.m_proxy.setSortData("order")
            self.m_proxy.setSortLocaleAware(True)
            self.m_proxy.sort(0, Qt.AscendingOrder)
            self.m_proxy.setSortRole(self.ObjectRole)

    @Slot(str, QJsonArray, int, QJsonArray, QJsonArray)
    def setSearch(self, model_method_search, domain, maxlimit, ordertryton,
                  fields):
        self.m_maxLimit = maxlimit
        self.m_domain = domain  #.toVariantList()
        self.m_orderTryton = ordertryton  #.toVariantList()
        self.setFields(fields)
        self.m_model_method_search = model_method_search

    @Slot(str)
    def setModelMethod(self, model_method_search):
        self.m_model_method_search = model_method_search

    @Slot(QJsonArray)
    def setDomain(self, domain):
        self.m_domain = domain

    @Slot(int)
    def setMaxLimit(self, maxlimit):
        self.m_maxLimit = maxlimit

    @Slot(QJsonArray)
    def setOrder(self, ordertryton):
        self.m_orderTryton = ordertryton

    @Slot(QJsonArray)
    def setFields(self, fields):  # si es [], son todos
        self.m_fields = fields
        self.m_fieldsPoint = []
        for f in self.m_fields.toVariantList():
            if f.find(".") != -1:
                self.m_fieldsPoint.append(f)

    @Slot(str)
    def setLanguage(self, language):
        self.m_locale = QLocale(language)

    @Slot()
    @Slot(QJsonArray)
    @Slot(QJsonArray, int)
    def find(self, domain=QJsonArray(), maxlimit=-1):
        #        if domain!=QJsonArray():
        self.m_domain = domain  #.toVariantList()
        self.initSearch(maxlimit)

    @Slot()
    @Slot(int)
    def initSearch(self, maxlimit=-1):
        self.clear()
        self.m_hasIndexOfId = {}
        self.nextSearch(maxlimit)

    def addResult(self, result, update=False):  #QJsonArray
        jsonobj = {}
        mis = self._count()
        for res in result:
            mid = int(res["id"])
            mapJsonDoc = res
            jsonobj = {}
            order = "" if self.m_order == "" else mapJsonDoc[
                self.m_order].strip()
            metadata = ""
            jsonobj = mapJsonDoc
            if self.boolMetadata:
                doct = QJsonDocument(mapJsonDoc)
                metadata = doct.toJson(
                    QJsonDocument.Compact).data().decode("utf-8")
#            if self.m_fields!= QJsonArray():
            if len(self.m_fieldsPoint) > 0:
                fieldsdoc = list(mapJsonDoc)
                for fp in self.m_fieldsPoint:
                    if fp not in fieldsdoc:
                        lfp = fp.split(".")
                        for li in range(len(lfp) - 1):
                            lfp[li] = lfp[li] + "."
                        temp = jsonobj[lfp[0]]
                        for c in lfp[1:]:
                            if temp != None:
                                temp = temp[c]
                        jsonobj[fp] = temp

            for vp in self.m_fieldsFormatDecimal:
                v = vp[0]
                if jsonobj.__contains__(v):
                    if jsonobj[v] != None:
                        if jsonobj[v].__contains__("decimal"):
                            jsonobj[v + "_format"] = self.m_locale.toString(
                                float(jsonobj[v]["decimal"]), 'f',
                                vp[1])  #add suport
                        else:
                            jsonobj[v + "_format"] = ""
                    else:
                        jsonobj[v + "_format"] = ""
            for v in self.m_fieldsFormatDateTime:
                mfield = v[0]
                mformat = v[1]
                if jsonobj.__contains__(mfield):
                    mdateTime = QDateTime()
                    if jsonobj[mfield] != None:
                        if jsonobj[mfield].__contains__("__class__"):
                            if jsonobj[mfield]["__class__"] == "date":
                                mdateTime = QDateTime(
                                    QDate(jsonobj[mfield]["year"],
                                          jsonobj[mfield]["month"],
                                          jsonobj[mfield]["day"]), QTime())
                            if jsonobj[mfield]["__class__"] == "datetime":
                                mdateTime = QDateTime(
                                    QDate(jsonobj[mfield]["year"],
                                          jsonobj[mfield]["month"],
                                          jsonobj[mfield]["day"]),
                                    QTime(jsonobj[mfield]["hour"],
                                          jsonobj[mfield]["minute"],
                                          jsonobj[mfield]["second"]))

                            jsonobj[mfield +
                                    "_format"] = mdateTime.toString(mformat)
                        else:
                            jsonobj[mfield + "_format"] = ""
                    else:
                        jsonobj[mfield + "_format"] = ""

            if update == False:
                dataJson = DataJson(mid, order, jsonobj, metadata, self)
                self.append(dataJson)

                self.m_hasIndexOfId[mid] = mis
                mis += 1
            else:
                index = self.indexisOfId(mid)
                if index != -1:
                    self.at(index).setProperty("order", order)
                    self.at(index).setProperty("json", jsonobj)
                    self.at(index).setProperty("metadata", metadata)

    @Slot()
    @Slot(int)
    def nextSearch(self, maxlimit=-1):  # metodo asincronico
        self.openBusy()
        limit = self.m_maxLimit
        if maxlimit != -1:
            limit = maxlimit
        params = QJsonArray()
        params.append(self.m_domain)
        params.append(self._count())
        params.append(limit)
        params.append(self.m_orderTryton)
        params.append(self.m_fields)
        params.append(self.m_preferences)
        if self.boolSynchro:
            #            result = self.m_qjsonnetwork.callDirect("nextSearch"+self.objectName(), self.m_model_method_search+".search_read" ,params)
            result = self.m_qjsonnetwork.recursiveCall(
                "nextSearch" + self.objectName(),
                self.m_model_method_search + ".search_read", params)
            reValue = result["data"]
            if reValue.__class__() == {}:
                if reValue.__contains__("result"):
                    if reValue["result"].__class__() == []:
                        self.addResult(reValue["result"])
                        self.closeBusy()

        else:
            self.m_qjsonnetwork.call(
                "nextSearch" + self.objectName(),
                self.m_model_method_search + ".search_read", params)

    @Slot(QJsonArray)  # metodo asincronico
    def updateRecords(self, ids):  #update record with tryton,
        self.openBusy()
        params = QJsonArray()
        params.append(ids)
        params.append(self.m_fields)
        params.append(self.m_preferences)
        if self.boolSynchro:
            #            result = self.m_qjsonnetwork.callDirect("updateRecords"+self.objectName(), self.m_model_method_search+".read" ,params)
            result = self.m_qjsonnetwork.recursiveCall(
                "updateRecords" + self.objectName(),
                self.m_model_method_search + ".read", params)
            reValue = result["data"]
            if reValue.__class__() == {}:
                if reValue.__contains__("result"):
                    if reValue["result"].__class__() == []:
                        self.addResult(reValue["result"], True)
                        self.closeBusy()

        else:
            self.m_qjsonnetwork.call("updateRecords" + self.objectName(),
                                     self.m_model_method_search + ".read",
                                     params)

    @Slot(int)
    def removeItem(self,
                   mid):  # elimina solo en memory, no afecta a base datos
        index = self.indexisOfId(mid)
        if index != -1:
            self.m_hasIndexOfId.pop(mid)
            self.removeAt(index)

    @Slot(QJsonArray)
    def addFieldFormatDecimal(self, fields):
        #ModelArticulo.addFieldFormatDecimal(['total_amount']);
        self.m_fieldsFormatDecimal = []
        for v in fields.toVariantList():
            if v.__class__() == '':
                self.m_fieldsFormatDecimal.append([v, 2])
            elif v.__class__() == []:
                if v.__len__() == 2:
                    if v[0].__class__() == '' and v[1].__class__() == 0:
                        self.m_fieldsFormatDecimal.append(v)

    @Slot(QJsonArray)
    def addFieldFormatDateTime(self, fields):
        #ModelArticulo.addFieldFormatDateTime([['invoice_date','dd/MM/yy'],['create_date','dd/MM/yy hh:mm:ss']]);
        self.m_fieldsFormatDateTime = []
        for v in fields.toVariantList():
            if v.__class__() == []:
                if v.__len__() == 2:
                    if v[0].__class__() == '' and v[1].__class__() == '':
                        self.m_fieldsFormatDateTime.append(v)

    signalResponse = Signal(str, int)
    signalResponseData = Signal(str, int, "QJsonObject")  #QJsonObject = dict

    @Slot(str, int, dict)  # obsoleto mejor usar calldirect!
    def slotJsonConnect(self, pid, option, data):  #cath datos de call,
        if pid == "nextSearch" + self.objectName():
            if option == 2:  #result
                dataObject = data["data"]
                if dataObject.__contains__("result"):
                    if dataObject["result"].__class__() == []:
                        self.addResult(dataObject["result"])
                        self.signalResponseData.emit(
                            "nextSearch", option,
                            {})  # ok envio emit de confirmacion
                else:
                    #print("la data",data)
                    self.signalResponseData.emit(
                        "nextSearch", 5, data)  #puede ser un error 403 timeout
            else:
                self.signalResponseData.emit("nextSearch", option,
                                             data)  #dejo cruzar los datos
        if pid == "updateRecords" + self.objectName():
            if option == 2:  #result
                dataObject = data["data"]
                if dataObject.__contains__("result"):
                    if dataObject["result"].__class__() == []:
                        self.addResult(dataObject["result"], True)
                        self.signalResponseData.emit(
                            "updateRecords", option,
                            {})  # ok envio emit de confirmacion
                else:
                    #print("la data",data)
                    self.signalResponseData.emit(
                        "updateRecords", 5,
                        data)  #puede ser un error 403 timeout
            else:
                self.signalResponseData.emit("nextSearch", option,
                                             data)  #dejo cruzar los datos

    def setProxy(self, proxp):
        self.m_proxy = proxp

    def setJsonConnect(self, jchac):  #=None):#(QJsonNetwork *jchac=nullptr);
        self.m_qjsonnetwork = jchac
        self.connectSlotJC()

    def connectSlotJC(self):
        if self.boolSynchro == False:
            self.m_qjsonnetwork.signalResponse.connect(self.slotJsonConnect)
#        self.connect(self.m_qjsonnetwork, SIGNAL(signalResponse(QString,int,QJsonObject)),
#                     self, SLOT(slotJsonConnect(QString,int,QJsonObject)));

    def setEngine(self, engine):
        self.m_engine = engine

    def openBusy(self):
        if self.autoBusy:
            if self.m_engine != None:
                root = self.m_engine.rootObjects()[0]
                QMetaObject.invokeMethod(root, "openBusy")

    def closeBusy(self):
        if self.autoBusy:
            if self.m_engine != None:
                root = self.m_engine.rootObjects()[0]
                QMetaObject.invokeMethod(root, "closeBusy")

    @Slot(bool)
    def setAutoBusy(self, busy):
        self.autoBusy = busy

    @Slot(bool)
    def setSynchro(self, syn):
        self.boolSynchro = syn
        self.connectSlotJC()

    def initProxy(self):
        if self.m_order != "":
            self.m_proxy.setSortData("order")
            self.m_proxy.setSortLocaleAware(True)
            self.m_proxy.sort(0, Qt.AscendingOrder)
            self.m_proxy.setSortRole(self.ObjectRole)

        self.m_proxy.setFilterRoles("metadata")
        self.m_proxy.setFilterRole(self.ObjectRole)
        self.m_proxy.setDynamicSortFilter(True)
        self.m_proxy.setSourceModel(self)

    def isJsonObject(self, mtextdoc):
        pass
Exemple #2
0
class SliderBar(QWidget):
    value_changed = Signal(float)

    def __init__(self,
                 title: str = '',
                 value: float = 0,
                 min_value: float = 0,
                 max_value: float = 100,
                 displayed_value_factor: float = 1,
                 parent: QWidget = None):
        super().__init__(parent)

        self._value = value
        self._min_value = min_value
        self._max_value = max_value
        self._displayed_value_factor = displayed_value_factor

        self._title_label = QLabel(title)

        self._color = DEFAULT_BAR_COLOR

        self._locale = QLocale(QLocale.English)
        self._locale.setNumberOptions(self._locale.numberOptions()
                                      | QLocale.RejectGroupSeparator)

        validator = QDoubleValidator(self._min_value, self._max_value, 2)
        validator.setNotation(QDoubleValidator.StandardNotation)
        validator.setLocale(self._locale)

        self._value_line_edit = SliderValueLineEdit()
        self._value_line_edit.setValidator(validator)
        max_label_width = self._value_line_edit.fontMetrics().width(
            self._value_to_str(self.max_value))
        self._value_line_edit.setFixedWidth(6 + max_label_width)
        self._value_line_edit.editingFinished.connect(
            self._on_value_line_edit_editing_finished)

        h_layout = QHBoxLayout(self)
        h_layout.setContentsMargins(4, 0, 4, 0)
        # h_layout.setSpacing(0)

        h_layout.addWidget(self._title_label, 0, Qt.AlignLeft)
        h_layout.addWidget(self._value_line_edit, 0, Qt.AlignRight)

        self._update_value_line_edit()

    @property
    def title(self) -> str:
        return self._title_label.text()

    @title.setter
    def title(self, value: str):
        self._title_label.setText(value)

    @property
    def value(self) -> float:
        return self._value

    @value.setter
    def value(self, value: float):
        value = max(min(value, self._max_value), self._min_value)
        if self._value != value:
            self._value = value

            self._update_value_line_edit()
            self.update()

            self.value_changed.emit(self._value)

    @property
    def min_value(self) -> float:
        return self._min_value

    @min_value.setter
    def min_value(self, value: float):
        if self._min_value != value:
            self._min_value = value

            if self.value < self._min_value:
                self.value = self._min_value
            else:
                self.update()

    @property
    def max_value(self) -> float:
        return self._max_value

    @max_value.setter
    def max_value(self, value: float):
        if self._max_value != value:
            self._max_value = value

            if self.value > self._max_value:
                self.value = self._max_value
            else:
                self.update()

    @property
    def color(self) -> QColor:
        return self._color

    @color.setter
    def color(self, value: QColor):
        if self._color != value:
            self._color = value
            self.update()

    @property
    def font_height(self):
        return self._title_label.fontMetrics().height()

    def set_focus(self):
        self._value_line_edit.setFocus()

    def increase_value(self, factor: float = 1):
        self.change_value_by_delta(1 * factor)

    def decrease_value(self, factor: float = 1):
        self.change_value_by_delta(-1 * factor)

    def change_value_by_delta(self, delta: float):
        self.value += delta
        self._value_line_edit.selectAll()

    def paintEvent(self, event: QPaintEvent):
        super().paintEvent(event)

        painter = QPainter(self)
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.color)
        painter.drawRect(
            0, 0,
            round((self._value - self._min_value) /
                  (self._max_value - self._min_value) * self.width()),
            self.height())

    def mouseMoveEvent(self, event: QMouseEvent):
        self._update_value_by_x(event.x())

        event.accept()

    def mousePressEvent(self, event: QMouseEvent):
        self.set_focus()

        self._update_value_by_x(event.x())

        event.accept()

    def mouseDoubleClickEvent(self, event: QMouseEvent):
        self._value_line_edit.selectAll()

        event.accept()

    def keyPressEvent(self, event: QKeyEvent):
        if event.key() == Qt.Key_Up:
            self.increase_value()
        elif event.key() == Qt.Key_Down:
            self.decrease_value()
        elif event.key() == Qt.Key_PageUp:
            self.increase_value(10)
        elif event.key() == Qt.Key_PageDown:
            self.decrease_value(10)

    def wheelEvent(self, event: QWheelEvent):
        value_delta = event.angleDelta().y() / 120
        if event.modifiers() & Qt.ControlModifier:
            value_delta *= 10
        self.set_focus()
        self.increase_value(value_delta)

        event.accept()

    def _on_value_line_edit_editing_finished(self):
        self.value, ok = self._locale.toFloat(self._value_line_edit.text())

    def _update_value_by_x(self, x: int):
        self.value = (self.max_value -
                      self.min_value) * x / self.width() + self.min_value

    def _update_value_line_edit(self):
        self._value_line_edit.setText(self._value_to_str(self.value))

    def _value_to_str(self, value: float) -> str:
        return self._locale.toString(
            float(value * self._displayed_value_factor), 'f', 2)