'Qthread with reading json values and sending json with toggle button issues

I have some issues when toggle button is set to OFF it goes back to ON as json read still gets not refreshed value and kicks in slot_method. But I need this if statement to read initial value when launching the app and this mode allready can be selected from hardware controller. How it can be reworked that on toggle button click 1 json read thread could be excluded ?

py_toggle.py

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *


class PyToggle(QCheckBox):
    def __init__(
            self,
            width=60,
            bg_color="#777",
            circle_color="#DDD",
            active_color="#3A3A66",
            animation_curve=QEasingCurve.OutBounce
    ):
        QCheckBox.__init__(self)

        # SET DEFAULT PARAMETERS
        self.setFixedSize(width, 28)
        self.setCursor(Qt.PointingHandCursor)

        # COLORS

        self._bg_color = bg_color
        self._circle_color = circle_color
        self._active_color = active_color

        # CREATE ANIMATION

        self._circle_position = 3
        self.animation = QPropertyAnimation(self, b"circle_position", self)
        self.animation.setEasingCurve(animation_curve)
        self.animation.setDuration(400)  # Time in milliseconds

        # CONNECT STATE CHANGED

        # self.stateChanged.connect(self.debug)
        self.stateChanged.connect(self.start_transition)
        # self.stateChanged.connect()

    # CREATE NEW SET AND GET PROPERTIE

    @Property(float)  # Decorator Getter
    def circle_position(self):
        return self._circle_position

    @circle_position.setter
    def circle_position(self, pos):
        self._circle_position = pos
        self.update()

    # def state(self):
    #     print(f"Status: {self.isChecked()}")

    def start_transition(self, value):
        self.animation.stop()  # Stop animation if running
        if value:
            self.animation.setEndValue(self.width() - 26)
        else:
            self.animation.setEndValue(3)
        # START ANIMATION
        self.animation.start()

    # SET NEW HIT AREA

    def hitButton(self, pos: QPoint):
        return self.contentsRect().contains(pos)

    # DRAW NEW ITEMS
    def paintEvent(self, e):
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing)

        # SET AS NO PEN
        p.setPen(Qt.NoPen)

        # DRAW RECTANGLE
        rect = QRect(0, 0, self.width(), self.height())

        if not self.isChecked():
            # DRAW BG
            p.setBrush(QColor(self._bg_color))
            p.drawRoundedRect(0, 0, rect.width(), self.height(), self.height() / 2, self.height() / 2)

            # DRAW CIRCLE
            p.setBrush(QColor(self._circle_color))
            p.drawEllipse(self._circle_position, 3, 22, 22)
        else:
            # DRAW BG
            p.setBrush(QColor(self._active_color))
            p.drawRoundedRect(0, 0, rect.width(), self.height(), self.height() / 2, self.height() / 2)

            # DRAW CIRCLE
            p.setBrush(QColor(self._circle_color))
            p.drawEllipse(self._circle_position, 3, 22, 22)

        # END DRAW
        p.end()

test.py

import sys

import requests
from PySide2.QtCore import (QTimer, QThread, Signal)
from PySide2.QtWidgets import *

from py_toggle import PyToggle


class WorkerThread(QThread):
    measurements_signals = Signal(str, name = 'm_signals')  # declare the signal

    def __init__(self, parent=None):
        QThread.__init__(self)

        self.timer = QTimer()
        self.timer.timeout.connect(lambda: WorkerThread.run(self))
        self.timer.setInterval(6000)  # 6000ms = 6s
        self.timer.start()

    def run(self):
        url = "http://192.168.8.150/json"

        try:
            res = requests.get(url)
            msg = res.json()
            print(msg)
            try:
                if res.status_code == 200:
                    quiet = msg["heatpump"][18]["Value"]
                    self.measurements_signals.emit(quiet)
                else:
                    print("Not Working")
            except requests.exceptions.InvalidURL or requests.exceptions.ConnectionError as err:
                print(err)

        except requests.exceptions.InvalidURL or requests.exceptions.ConnectionError as err:
            print(err)

    def stop(self):
        self.terminate()
        print("stop")


class Tester(QWidget):
    def __init__(self, parent = None):
        super(Tester, self).__init__(parent)


        # ==> TOGGLE BUTTON1
        self.setWindowTitle("Test")
        self.resize(200, 150)
        layout = QGridLayout()
        self.toggle = PyToggle()
        layout.addWidget(self.toggle)
        self.toggle.stateChanged.connect(self.postCommand)
        self.setLayout(layout)



        # ==> Worker Thread start

        self.wt = WorkerThread()  # This is the thread object
        self.wt.start()
        # Connect the signal from the thread to the slot_method
        self.wt.measurements_signals.connect(self.slot_method)  ### 3) connect to the slot
        app.aboutToQuit.connect(self.wt.stop)  # to stop the thread when closing the GUI

    def slot_method(self, quiet):

        if quiet == "1":
            self.toggle.setChecked(True)

    def postCommand(self):
        if self.toggle.isChecked():
            setting = "SetQuietMode=1"
        else:
            setting = "SetQuietMode=0"

        url = f"http://192.168.8.150/command?{setting}"
        r = requests.request('GET', url)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = Tester()
    form.show()
    sys.exit(app.exec_())


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source