Ejemplo n.º 1
0
    def ui_setup_coord(self, coord: str, unite: str):
        """Configure un duo de widget (QLabel et QLCDNumber dans un QLayout)
        et renvoie le QLCDNumber"""

        label_coord = QLabel()
        label_coord.setText('{0} ({1})'.format(coord, unite))
        self.layout_coord.addWidget(label_coord)
        lcd_number_coord = QLCDNumber()
        lcd_number_coord.setFixedSize(QLCD_SIZE1)
        self.layout_coord.addWidget(lcd_number_coord)
        return lcd_number_coord
Ejemplo n.º 2
0
class PlayTimer(QWidget):
    done = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.init_ui()

    def init_ui(self):
        self.setProperty('id', 'timer')
        vbox = QVBoxLayout(self)

        self.instructions = QLabel(self)
        self.instructions.setProperty("id", "timer-instruction")
        self.lcd = QLCDNumber(2, self)
        self.clock = QBasicTimer()

        vbox.addWidget(self.instructions)
        vbox.addWidget(self.lcd)
        vbox.setAlignment(Qt.AlignCenter)
        vbox.setAlignment(self.instructions, Qt.AlignCenter)

    def timerEvent(self, e):
        if self.preptime > 1:
            self.preptime -= 1
            self.lcd.display(self.preptime)
        elif self.runtime == 60:
            self.lcd.display(self.runtime)
            self.runtime -= 1
            self.instructions.setText("Play!")
        elif self.runtime > 0:
            self.lcd.display(self.runtime)
            self.runtime -= 1
        else:
            self.clock.stop()
            self.done.emit()

    def resizeEvent(self, e):
        self.lcd.setFixedSize(e.size().width() // 2, e.size().height() // 2)

    def start_timer(self):
        self.preptime, self.runtime = 3, 60
        self.instructions.setText("Get ready!")
        self.lcd.display(self.preptime)
        self.clock.start(1000, self)
Ejemplo n.º 3
0
class MainWidget(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        layout = QHBoxLayout(self)  # Main layout of the widget

        # Creating a group box with a title for each of the widget's parts. Adding a layout for each of the group boxes.
        box_labels = ['Display', 'Sweep control', 'Switch']
        self.group_box = {}
        self.group_box_layout = {}
        for label in box_labels:
            self.group_box_layout[label] = QGridLayout(
            )  # Creating a layout for each group box
            self.group_box[label] = QGroupBox(label)  # Creating a group box
            self.group_box[label].setLayout(
                self.group_box_layout[label]
            )  # Setting layouts to the group boxes
            layout.addWidget(self.group_box[label]
                             )  # Setting group boxes to the main layout

        # Creating an lcd number to be a value monitor and adding it to the layout of the 'Display' group box
        self.value_lcd = QLCDNumber(6)
        self.value_lcd.setSmallDecimalPoint(True)
        self.value_lcd.display('0.0000')
        self.value_lcd.setFixedSize(320, 85)
        self.group_box_layout['Display'].addWidget(self.value_lcd,
                                                   0,
                                                   0,
                                                   4,
                                                   1,
                                                   alignment=Qt.AlignCenter)

        # Creating indicators for all the gui
        indicator_labels = [
            'Clamped', 'Persistent', 'Sweep limit', 'Quench', 'Hold',
            'To zero', 'To set', 'Heater'
        ]
        indicator_orders = [
            'i-l', 'i-l', 'i-l', 'i-l', 'l-i', 'l-i', 'l-i', 'l-i'
        ]
        indicator_alignments = ['h', 'h', 'h', 'h', 'v', 'v', 'v', 'v']
        self.indicator = {}
        self.sweep_control_btn = {}
        self.heater_btn = Button()
        k = 0
        for label, order, alignment in zip(indicator_labels, indicator_orders,
                                           indicator_alignments):
            self.indicator[label] = Indicator(label, alignment, order, 12)
            if k < 4:
                # Adding corresponding indicators to the 'Display' layout
                self.group_box_layout['Display'].addWidget(
                    self.indicator[label], k, 1, alignment=Qt.AlignLeft)
            elif k < 7:
                # Adding corresponding indicators to the 'Sweep control' layout. Also creating buttons and adding
                # them as well
                self.group_box_layout['Sweep control'].addWidget(
                    self.indicator[label], 0, k, alignment=Qt.AlignCenter)
                self.sweep_control_btn[label] = Button()
                self.group_box_layout['Sweep control'].addWidget(
                    self.sweep_control_btn[label],
                    1,
                    k,
                    alignment=Qt.AlignCenter)
            else:
                # Adding a 'Heater' indicator to the 'Switch' group box layout. Adding a button to switch the heater
                self.group_box_layout['Switch'].addWidget(
                    self.indicator[label], 0, 0, alignment=Qt.AlignCenter)
                self.group_box_layout['Switch'].addWidget(
                    self.heater_btn, 1, 0, alignment=Qt.AlignCenter)
            k += 1
Ejemplo n.º 4
0
class DisplayRobot(anr.Robot, QWidget):
    """Une combinaison de l'objet Robot et d'un QWidget"""
    def __init__(self, parent_annu, rid):
        self.parent_annu = parent_annu
        self.backend = self.parent_annu.backend
        anr.Robot.__init__(self, rid)
        QWidget.__init__(self)

        self.is_ghost = self.rid[-6:] == '_ghost'

        self.ping = 0

        # Création des widgets de la boite robot
        self.groupbox_robots = QWidget()
        self.layout_tab_robot = QVBoxLayout(self)
        self.layout_box_robot = QVBoxLayout(self.groupbox_robots)
        self.scroll_area = QScrollArea()
        self.layout_name_delete = QHBoxLayout()
        self.button_delete = QPushButton()
        self.layout_coord = QHBoxLayout()
        self.layout_last_message = QHBoxLayout()
        self.groupbox_actuators = QGroupBox()
        self.groupbox_sensors = QGroupBox()
        self.layout_box_actuators = QVBoxLayout(self.groupbox_actuators)
        self.layout_box_sensors = QVBoxLayout(self.groupbox_sensors)
        self.label_last_message = QLabel()
        self.lcdnumber_las_message = QLCDNumber()
        self.layout_last_command = QHBoxLayout()
        self.label_position_command = QLabel()
        self.qlineedit_pos_cmd = QLineEdit()
        self.emergency_button = QPushButton()
        self.progressbar_battery = QProgressBar()

        # Configuration des widgets de la boite robot
        self.ui_setup_tab_robot()

        # Création d'un QTimer pour la mise à jour du ping du robot
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_ping)
        self.timer.start(100)

    def ui_setup_tab_robot(self):
        """ Configure l'ensemble de l'onglet robot"""

        # Configuration de la scroll bar
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setFrameShape(QFrame.NoFrame)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll_area.setWidget(self.groupbox_robots)
        self.layout_tab_robot.addWidget(self.scroll_area)

        self.button_delete.setFixedSize(175, 25)
        if self.is_ghost:
            self.button_delete.setText("Oublier")
            self.button_delete.clicked.connect(lambda: self.backend.forget_robot(self.rid))
        else:
            self.button_delete.setText("Eteindre")
            self.button_delete.clicked.connect(lambda: self.backend.stopandforget_robot(self.rid))

        self.emergency_button.setText("STOP")
        self.emergency_button.setStyleSheet(EMERGENCY_BUTTON)
        if self.is_ghost:
            self.emergency_button.setText("Lecture")
            self.emergency_button.setStyleSheet(READONLY_BUTTON)
        self.emergency_button.setFixedSize(175, 25)
        if not self.is_ghost:
            self.emergency_button.clicked.connect(
                    lambda: self.backend.emergency_stop_robot(self.rid))
        self.layout_name_delete.addWidget(self.button_delete)
        self.layout_name_delete.addWidget(self.emergency_button)
        self.layout_box_robot.addLayout(self.layout_name_delete)

        # Configuration de l'affichage des coordonnées"
        self.lcdnumber_x = self.ui_setup_coord("X", "mm")
        self.lcdnumber_y = self.ui_setup_coord("Y", "mm")
        self.lcdnumber_theta = self.ui_setup_coord("θ", "°")
        self.layout_box_robot.addLayout(self.layout_coord)

        # Configuration de l'affichage du dernier message reçu
        self.label_last_message.setText("Dernière MAJ (s)")
        self.layout_last_message.addWidget(self.label_last_message)
        self.lcdnumber_las_message.setFixedSize(QLCD_SIZE2)
        self.layout_last_message.addWidget(self.lcdnumber_las_message)
        self.layout_box_robot.addLayout(self.layout_last_message)

        # Confiuration de l'envoyeur de commandes de postion
        self.label_position_command.setText("Dern. PosCmd:")
        self.layout_last_command.addWidget(self.label_position_command)
        self.qlineedit_pos_cmd = QLineEdit()
        self.qlineedit_pos_cmd.setText("1500 : 1000: 000")
        self.qlineedit_pos_cmd.setInputMask("0000 : 0000 : 000")
        self.qlineedit_pos_cmd.setFixedSize(220, 25)
        self.qlineedit_pos_cmd.editingFinished.connect(self.on_editing_finished)
        self.qlineedit_pos_cmd.setAlignment(QT_CENTER)
        self.layout_last_command.addWidget(self.qlineedit_pos_cmd)
        self.layout_box_robot.addLayout(self.layout_last_command)

        # Configuration de la Configure la boite actionneurs
        self.groupbox_actuators.setAlignment(QT_CENTER)
        self.groupbox_actuators.setTitle("Actionneurs")
        self.layout_box_robot.addWidget(self.groupbox_actuators, 0, QT_TOP)

        # Configuration de la boite capteurs
        self.groupbox_sensors.setAlignment(QT_CENTER)
        self.groupbox_sensors.setTitle("Capteurs:")
        self.layout_box_robot.addWidget(self.groupbox_sensors, 0, QT_TOP)

    def ui_setup_coord(self, coord: str, unite: str):
        """Configure un duo de widget (QLabel et QLCDNumber dans un QLayout)
        et renvoie le QLCDNumber"""

        label_coord = QLabel()
        label_coord.setText('{0} ({1})'.format(coord, unite))
        self.layout_coord.addWidget(label_coord)
        lcd_number_coord = QLCDNumber()
        lcd_number_coord.setFixedSize(QLCD_SIZE1)
        self.layout_coord.addWidget(lcd_number_coord)
        return lcd_number_coord

    def set_pos(self, x, y, theta):
        """Met à jour la position du robot

        Entrée:
        - x (float)
        - y (float)
        - theta (float)
        """
        anr.Robot.set_pos(self, x, y, theta)
        # Mise à jour des valeurs affichées par les QLCDNUmber
        self.lcdnumber_x.display(self.x)
        self.lcdnumber_y.display(self.y)
        self.lcdnumber_theta.display(self.theta)

        self.update_ping()

    def create_eqp(self, eqp_name, eqp_type, *args):
        """Crée un nouvel équipement, et l'ajoute au robot
        (sans avoir besoin de manipuler des objets Equipement

        Entrée:
            - eqp_name (str)
            - eqp_type (str): le type d'équipement,
            à choisir en inscrivant la chaine de caractère du nom de classe associé:
                'Equipement' / 'Actionneur' / 'Binaire' / 'Capteur'
            - args (tuple): tous les autres arguments liés à la création des eqps
                si actionneur ou capteur: (min, max, step (, unit))
        """
        nv_eqp = None
        if eqp_type == "Actionneur":
            min_v = args[0]
            max_v = args[1]
            step = args[2]
            if len(args) == 4:
                unit = args[3]
            else:
                unit = None
            nv_eqp = DisplayActionneur(self, eqp_name, min_v, max_v, step, unit)
        elif eqp_type == "Binaire":
            nv_eqp = DisplayBinaire(self, eqp_name)
        elif eqp_type == "Capteur":
            min_v = args[0]
            max_v = args[1]
            step = args[2]
            if len(args) == 4:
                unit = args[3]
            else:
                unit = None
            nv_eqp = DisplayCapteur(self, eqp_name, min_v, max_v, step, unit)

        if nv_eqp is not None:
            self.updt_eqp(nv_eqp)

    def updt_eqp(self, equipement):
        """Ajoute/met à jour un actionneur du robot

        Entrée:
        - equipement (Equipement)
        """
        #l'équipement existe-t-til déjà?
        if self.equipements.get(equipement.nom, None) is not None:
            self.equipements[equipement.nom].hide() #suppression de la partie graphique
        anr.Robot.updt_eqp(self, equipement) #mise à jour de l'équipement (data)
        #ajout de la partie graphique au bon layout
        if isinstance(equipement, DisplayCapteur):
            self.layout_box_sensors.addWidget(self.equipements[equipement.nom])
        else:
            self.layout_box_actuators.addWidget(self.equipements[equipement.nom])
        self.equipements[equipement.nom].show() #affichage partie graphique

        #cache des groupbox vides
        has_act = False
        has_capt = False
        for eqp_rb in self.equipements.values():
            if isinstance(eqp_rb, DisplayCapteur):
                has_capt = True
            if isinstance(eqp_rb, DisplayBinaire) or isinstance(eqp_rb, DisplayActionneur):
                has_act = True
        if not has_capt:
            self.groupbox_sensors.hide()
        else:
            self.groupbox_sensors.show()
        if not has_act:
            self.groupbox_actuators.hide()
        else:
            self.groupbox_actuators.show()

    def remove_eqp(self, eqp_name):
        """Enlève un équipement repéré par son nom du robot

        Entrée:
        - eqp_name (str)"""
        self.equipements[eqp_name].hide()
        self.equipements[eqp_name].setParent(None)
        anr.Robot.remove_eqp(self, eqp_name)

    def update_ping(self):
        """ Calcul et met à jour le ping de la position """
        self.ping = round(abs(time.time() - self.last_updt_pos), 1)
        self.lcdnumber_las_message.display(format(self.ping))
        for eqp_rb in self.equipements.values():
            eqp_rb.update_ping()

    @pyqtSlot()
    def on_editing_finished(self):
        """"Appelée après la fin de l'édition de self.qlineedit_pos_cmd"""
        cmd = [int(i) for i in self.qlineedit_pos_cmd.text().split(' : ')]
        self.backend.sendposcmd_robot(self.rid, cmd)
Ejemplo n.º 5
0
class DisplayActionneur(anr.Actionneur, QWidget):
    """ Combinaison d'un objet Actionneur et d'un QWidget """
    def __init__(self, parent_robot, nom, min_val, max_val, step=1, unite=None):
        QWidget.__init__(self)
        anr.Actionneur.__init__(self, nom, min_val, max_val, step, unite)
        self.parent_robot = parent_robot
        self.backend = self.parent_robot.backend
        self.updated_outside = False
        self.ping = 0

        # Création des widgets de l'équipement
        self.gridlayout_eqp = QGridLayout(self)
        self.spaceritem_equipement = QSpacerItem(1, 15)
        self.label_name_equipement = QLabel()
        self.label_message_equipement = QLabel("Dernière MAJ (s)")
        self.lcdnumber_ping_eqp = QLCDNumber()

        self.layout_discret = QHBoxLayout()
        self.slider_equipement = QSlider(Qt.Horizontal)
        self.doublespinbox_eqp = QDoubleSpinBox()
        self.label_command = QLineEdit()
        self.label_last_command = QLabel()

        # Configuration des widgets de l'équipement
        self.ui_setup_equipement()

    #calcul et mise à jour du ping
    def update_ping(self):
        """Mise à jour du ping de l'équipement"""
        self.ping = round(abs(time.time() - self.last_updt), 1)
        self.lcdnumber_ping_eqp.display(format(self.ping))

    def ui_setup_equipement(self):
        """ Configure l'ensemble des widgets de l'équipement"""

        self.gridlayout_eqp.setAlignment(QT_TOP)

        if self.unite == "None" or self.unite is None:
            self.label_name_equipement.setText(self.nom)
        else:
            self.label_name_equipement.setText('{0} ({1})'.format(self.nom, self.unite))
        self.gridlayout_eqp.addWidget(self.label_name_equipement, 0, 0, 1, 1, QT_LEFT)

        self.label_message_equipement.setText("Dernière MAJ (s)")
        self.gridlayout_eqp.addWidget(self.label_message_equipement, 2, 0, 1, 2, QT_LEFT)
        self.lcdnumber_ping_eqp.setMaximumSize(QSize(75, 25))
        self.lcdnumber_ping_eqp.setFixedSize(QLCD_SIZE2)
        self.gridlayout_eqp.addWidget(self.lcdnumber_ping_eqp, 2, 1, 1, 1, QT_RIGHT)

        self.slider_equipement.setFixedSize(100, 30)
        self.slider_equipement.setMinimum(self.min_val)
        self.slider_equipement.setMaximum(self.max_val)
        self.slider_equipement.setSingleStep(self.step)
        self.slider_equipement.valueChanged.connect(self.onvaluechanged_slider)
        self.layout_discret.addWidget(self.slider_equipement)
        self.doublespinbox_eqp.setFixedSize(75, 30)
        self.doublespinbox_eqp.setMaximum(self.max_val)
        self.doublespinbox_eqp.setMinimum(self.min_val)
        self.doublespinbox_eqp.setSingleStep(self.step)
        self.doublespinbox_eqp.setAlignment(QT_CENTER)
        self.doublespinbox_eqp.valueChanged.connect(self.onvaluechanged)
        self.layout_discret.addWidget(self.doublespinbox_eqp)
        self.gridlayout_eqp.addLayout(self.layout_discret, 0, 1, 1, 1, QT_RIGHT)

        self.label_command.setText("None")
        self.label_command.setFixedSize(75, 30)
        self.label_command.setReadOnly(True)
        self.label_command.setAlignment(QT_CENTER)
        self.gridlayout_eqp.addWidget(self.label_command, 1, 1, 1, 1, QT_RIGHT)
        self.label_last_command.setText("Dern. Cmd:")
        self.gridlayout_eqp.addWidget(self.label_last_command, 1, 0, 1, 1, QT_LEFT)

    def set_state(self, valeur):
        """Change la valeur

        Entrée:
        - valeur (float)"""
        anr.Binaire.set_state(self, valeur)
        self.updated_outside = True
        self.slider_equipement.setValue(int(valeur))
        self.doublespinbox_eqp.setValue(valeur)
        self.updated_outside = False

    def updt_cmd(self, state):
        """Met à jour le timestamp de dernière commande
        et la dernière commande"""
        anr.Binaire.updt_cmd(self, state)
        self.label_command.setText(str(state))

    @pyqtSlot()
    def onvaluechanged(self):
        """ Affiche et envoie vers backend la dernière commande d'un actionneur discret"""
        if not self.updated_outside:
            self.backend.sendeqpcmd(self.parent_robot.rid, self.nom, self.doublespinbox_eqp.value())
            self.label_command.setText(str(self.doublespinbox_eqp.value()))
            self.slider_equipement.setValue(int(self.doublespinbox_eqp.value()))
            self.updt_cmd(self.doublespinbox_eqp.value())

    @pyqtSlot()
    def onvaluechanged_slider(self):
        """ Affiche et envoie vers backend la dernière commande d'un actionneur discret"""
        if not self.updated_outside:
            self.backend.sendeqpcmd(self.parent_robot.rid, self.nom, self.doublespinbox_eqp.value())
            self.label_command.setText(str(self.slider_equipement.value()))
            self.doublespinbox_eqp.setValue(self.slider_equipement.value())
            self.updt_cmd(self.slider_equipement.value())
Ejemplo n.º 6
0
class DisplayCapteur(anr.Capteur, QWidget):
    """Une combinaison de Capteur et d'un QWidget"""
    def __init__(self, parent_robot, nom, min_val, max_val, step=1, unite=None):
        QWidget.__init__(self)
        anr.Capteur.__init__(self, nom, min_val, max_val, step, unite)
        self.parent_robot = parent_robot
        self.backend = self.parent_robot.backend
        self.updated_outside = False
        self.ping = 0

        # Création des widgets de l'équipement
        self.gridlayout_eqp = QGridLayout(self)
        self.spaceritem_equipement = QSpacerItem(1, 15)
        self.label_name_equipement = QLabel()
        self.label_message_equipement = QLabel("Dernière MAJ (s)")
        self.lcdnumber_ping_eqp = QLCDNumber()

        self.lcdnumber_eqp = QLCDNumber()
        self.progressbar_eqp = QProgressBar()

        # Configuration des widgets de l'équipement
        self.ui_setup_equipement()

    def ui_setup_equipement(self):
        """ Configure l'ensemble des widgets de l'équipement"""

        self.gridlayout_eqp.setAlignment(QT_TOP)

        if self.unite == "None" or self.unite is None:
            self.label_name_equipement.setText(self.nom)
        else:
            self.label_name_equipement.setText('{0} ({1})'.format(self.nom, self.unite))
        self.gridlayout_eqp.addWidget(self.label_name_equipement, 0, 0, 1, 1, QT_LEFT)

        self.label_message_equipement.setText("Dernière MAJ (s)")
        self.gridlayout_eqp.addWidget(self.label_message_equipement, 2, 0, 1, 2, QT_LEFT)
        self.lcdnumber_ping_eqp.setMaximumSize(QSize(75, 25))
        self.lcdnumber_ping_eqp.setFixedSize(QLCD_SIZE2)
        self.gridlayout_eqp.addWidget(self.lcdnumber_ping_eqp, 2, 1, 1, 1, QT_RIGHT)

        if self.min_val is None or self.max_val is None or self.step is None:
            self.lcdnumber_eqp.setMinimumSize(150, 30)
            self.gridlayout_eqp.addWidget(self.lcdnumber_eqp, 0, 1, 1, 1, QT_RIGHT)
            self.progressbar_eqp.hide()
        else:
            self.progressbar_eqp.setRange(int(self.min_val), int(self.max_val))
            self.progressbar_eqp.setAlignment(QT_CENTER)
            self.progressbar_eqp.setFormat("%v")
            self.progressbar_eqp.setFixedSize(150, 30)
            self.gridlayout_eqp.addWidget(self.progressbar_eqp, 0, 1, 1, 1, QT_RIGHT)
            self.lcdnumber_eqp.hide()

    #calcul et mise à jour du ping
    def update_ping(self):
        """Mise à jour du ping de l'équipement"""
        self.ping = round(abs(time.time() - self.last_updt), 1)
        self.lcdnumber_ping_eqp.display(format(self.ping))

    def set_state(self, valeur):
        """Change la valeur

        Entrée:
        - valeur (float)"""
        anr.Binaire.set_state(self, valeur)
        self.updated_outside = True
        if self.valeur is not None:
            self.lcdnumber_eqp.display(self.valeur)
            self.progressbar_eqp.setValue(int(self.valeur))
        self.updated_outside = False
Ejemplo n.º 7
0
class DisplayBinaire(anr.Binaire, QWidget):
    """Une combinaison de l'objet Equipement et d'un QWidget"""
    def __init__(self, parent, nom):
        QWidget.__init__(self)
        anr.Binaire.__init__(self, nom)
        self.parent_robot = parent
        self.backend = self.parent_robot.backend
        self.updated_outside = False
        self.ping = 0

        # Création des widgets de l'équipement
        self.gridlayout_eqp = QGridLayout(self)
        self.spaceritem_equipement = QSpacerItem(1, 15)
        self.label_name_equipement = QLabel()
        self.label_message_equipement = QLabel("Dernière MAJ (s)")
        self.lcdnumber_ping_eqp = QLCDNumber()
        self.layout_binaire = QHBoxLayout()
        self.checkbox_equipement = QCheckBox()
        self.label_command = QLineEdit()
        self.label_last_command = QLabel()
        self.label_binaire = QLabel()

        # Configuration des widgets de l'équipement
        self.ui_setup_equipement()

    def ui_setup_equipement(self):
        """ Configure l'ensemble des widgets de l'équipement"""

        self.gridlayout_eqp.setAlignment(QT_TOP)

        if self.unite == "None" or self.unite is None:
            self.label_name_equipement.setText(self.nom)
        else:
            self.label_name_equipement.setText('{0} ({1})'.format(self.nom, self.unite))
        self.gridlayout_eqp.addWidget(self.label_name_equipement, 0, 0, 1, 1, QT_LEFT)

        self.gridlayout_eqp.addWidget(self.label_message_equipement, 2, 0, 1, 2, QT_LEFT)
        self.lcdnumber_ping_eqp.setMaximumSize(QSize(75, 25))
        self.lcdnumber_ping_eqp.setFixedSize(QLCD_SIZE2)
        self.gridlayout_eqp.addWidget(self.lcdnumber_ping_eqp, 2, 1, 1, 1, QT_RIGHT)

        self.label_binaire.setFixedSize(100, 20)
        self.checkbox_equipement.stateChanged.connect(self.oncheckbox_toggled)
        self.layout_binaire.addWidget(self.label_binaire)
        self.layout_binaire.addWidget(self.checkbox_equipement)
        self.gridlayout_eqp.addLayout(self.layout_binaire, 0, 1, 1, 1, QT_CENTER)

        self.label_command.setText("None")
        self.label_command.setFixedSize(75, 30)
        self.label_command.setReadOnly(True)
        self.label_command.setAlignment(QT_CENTER)
        self.gridlayout_eqp.addWidget(self.label_command, 1, 1, 1, 1, QT_RIGHT)
        self.label_last_command.setText("Dern. Cmd:")
        self.gridlayout_eqp.addWidget(self.label_last_command, 1, 0, 1, 1, QT_LEFT)

    def updt_cmd(self, state):
        """Met à jour le timestamp de dernière commande
        et la dernière commande"""
        anr.Binaire.updt_cmd(self, state)
        self.label_command.setText(str(state))

    def set_state(self, valeur):
        """Change la valeur

        Entrée:
        - valeur (float)"""
        anr.Binaire.set_state(self, valeur)
        self.updated_outside = True
        self.checkbox_equipement.setChecked(int(valeur))
        self.updated_outside = False

    #calcul et mise à jour du ping
    def update_ping(self):
        """Mise à jour du ping de l'équipement"""
        self.ping = round(abs(time.time() - self.last_updt), 1)
        self.lcdnumber_ping_eqp.display(format(self.ping))

    @pyqtSlot()
    def oncheckbox_toggled(self):
        """ Affiche et renvoie vers backend la dernière commande d'un actionneur binaire"""
        if not self.updated_outside:
            state = 1 if self.checkbox_equipement.isChecked() else 0
            self.backend.sendeqpcmd(self.parent_robot.rid, self.nom, state)
            self.updt_cmd(state)
Ejemplo n.º 8
0
class MainCode(QWidget):
    """MainCode of this program"""
    def __init__(self, parent=None):
        super(MainCode, self).__init__(parent)
        self.initUI()

    def initUI(self):
        """constructor"""

        self.main_hbox = QtWidgets.QHBoxLayout()
        self.main_vbox = QtWidgets.QVBoxLayout()

        self.main_elements_created = False
        self.test_elements_created = False
        self.result_elements_created = False
        self.settigs_elements_created = False

        self.square_color_before_change = QtCore.Qt.white
        self.square_color_after_change = QtCore.Qt.red

        self.music_player = QtMultimedia.QMediaPlayer()

        self.resize(1024, 768)
        self.setWindowTitle('Оценка скорости реакции')
        self.main_hbox.addLayout(self.main_vbox)
        self.setLayout(self.main_hbox)

        self.main_stage()

        self.show()

    def create_test_stage_elements(self):
        self.number_indicator = QLCDNumber(self)
        self.number_indicator.setDigitCount(5)
        self.number_indicator.display("00:00")
        self.number_indicator.setFixedSize(400, 100)
        self.timer = QtCore.QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(self.display)
        self.vbox_for_test_elements.addWidget(self.number_indicator,
                                              alignment=QtCore.Qt.AlignHCenter)
        self.vbox_for_test_elements.addStretch(1)

        self.btn_square = QtWidgets.QPushButton(' ', self)
        self.btn_square.setFixedSize(500, 500)
        self.btn_square.setShortcut("Space")
        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button,
                         self.square_color_before_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()
        self.vbox_for_test_elements.addWidget(self.btn_square,
                                              alignment=QtCore.Qt.AlignTop
                                              | QtCore.Qt.AlignHCenter)

        self.vbox_for_test_elements.addStretch(1)
        self.btn_start_stop = QtWidgets.QPushButton('Старт')
        self.btn_start_stop.setFixedSize(300, 50)
        self.btn_start_stop.clicked.connect(self.start_test)
        self.vbox_for_test_elements.addWidget(self.btn_start_stop,
                                              alignment=QtCore.Qt.AlignBottom
                                              | QtCore.Qt.AlignHCenter)

        self.main_elements_created = True
        self.main_vbox.addLayout(self.vbox_for_test_elements)

    def show_test_stage_elements(self):
        self.number_indicator.show()
        self.vbox_for_test_elements.addWidget(self.number_indicator,
                                              alignment=QtCore.Qt.AlignTop
                                              | QtCore.Qt.AlignHCenter)
        self.vbox_for_test_elements.addStretch(1)
        self.vbox_for_test_elements.addWidget(self.btn_square,
                                              alignment=QtCore.Qt.AlignTop
                                              | QtCore.Qt.AlignHCenter)
        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button,
                         self.square_color_before_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()
        self.btn_square.show()

        self.vbox_for_test_elements.addStretch(1)
        self.vbox_for_test_elements.addWidget(self.btn_start_stop,
                                              alignment=QtCore.Qt.AlignBottom
                                              | QtCore.Qt.AlignHCenter)
        self.btn_start_stop.show()
        self.main_vbox.addLayout(self.vbox_for_test_elements)

    def go_to_test_stage(self):
        """create buttons and open test window"""

        self.ms = 0
        self.sec = 0
        self.result_dict = {}
        self.list_of_reaction_times = []
        self.list_of_dicts_reaction_times_num_of_try = []
        self.list_of_falstarts = []

        self.vbox_for_test_elements = QtWidgets.QVBoxLayout()

        if self.test_elements_created == True:
            self.show_test_stage_elements()
        elif self.test_elements_created == False:
            self.create_test_stage_elements()

    def random_second(self, start, end):
        """generate random time in ms"""
        random_sec = start + random.randrange((end - start) * 10) / 10
        return random_sec

    def btn_square_click(self):
        """Останавливает таймер, обовляет счётчик попыток, вносит время реакции в список, обновляет цвет квадрата, БЕЗ звука"""

        self.timer.stop()
        self.count_of_try += 1

        if self.count_of_try == 100:
            self.stop_test_and_go_to_result_stage()

        if self.ms != 0:
            self.list_of_reaction_times.append(
                float(str(self.sec) + "." + str(self.ms)))
            self.list_of_dicts_reaction_times_num_of_try.append(
                {self.count_of_try: float(str(self.sec) + "." + str(self.ms))})
            self.test_start_timer()
        else:
            self.list_of_falstarts.append(self.count_of_try)

        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button,
                         self.square_color_before_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()
        self.sec = 0
        self.ms = 0
        self.number_indicator.display("%02d:%02d" % (self.sec, self.ms))

    def btn_square_click_with_sound(self):
        """Останавливает таймер, обовляет счётчик попыток, вносит время реакции в список, обновляет цвет квадрата, СО звуком"""

        self.timer.stop()
        self.count_of_try += 1

        if self.count_of_try == 100:
            self.stop_test_and_go_to_result_stage()

        if self.ms != 0:
            self.list_of_reaction_times.append(
                float(str(self.sec) + "." + str(self.ms)))
            self.list_of_dicts_reaction_times_num_of_try.append(
                {self.count_of_try: float(str(self.sec) + "." + str(self.ms))})
            self.test_start_timer_with_sonund()
        else:
            self.list_of_falstarts.append(self.count_of_try)

        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button,
                         self.square_color_before_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()
        self.sec = 0
        self.ms = 0
        self.number_indicator.display("%02d:%02d" % (self.sec, self.ms))

    def start_timer(self):
        """Вызывает срабатывание таймера """
        self.timer.start()

    def change_color_start_test_timer(self):
        """Запускает таймер, меняет цвет квадрата, без звука"""
        self.start_timer()

        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button, self.square_color_after_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()

    def change_color_start_test_timer_with_sound(self):
        """Запускает таймер, меняет цвет квадрата, запускает срабатывание звука"""
        self.start_timer()

        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button, self.square_color_after_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()
        self.music_player.play()

    def test_start_timer(self):
        """Запускает внутренний таймер до смены цвета"""
        QtCore.QTimer.singleShot((self.random_second(0.5, 3.0) * 1000),
                                 self.change_color_start_test_timer)

    def test_start_timer_with_sonund(self):
        """Запускает внутренний таймер до смены цвета и запуска звука"""
        QtCore.QTimer.singleShot((self.random_second(0.5, 3.0) * 1000),
                                 self.change_color_start_test_timer_with_sound)

    def start_test(self):
        """Выбирает какой метод запустить: со звуком или без звука, меняет название и функцию кнопки'старт', объявляет счётчик попыток"""
        try:
            if self.sound_checkbox.checkState() == 2:
                self.test_start_timer_with_sonund()
                self.btn_square.clicked.connect(
                    self.btn_square_click_with_sound)
            elif self.sound_checkbox.checkState() == 0:
                self.test_start_timer()
                self.btn_square.clicked.connect(self.btn_square_click)
        except:
            self.test_start_timer()
            self.btn_square.clicked.connect(self.btn_square_click)

        self.count_of_try = 0

        self.btn_start_stop.setText('Стоп')
        self.btn_start_stop.clicked.disconnect()
        self.btn_start_stop.clicked.connect(
            self.stop_test_and_go_to_result_stage)
        self.btn_start_stop.setShortcut("Esc")

    def stop_test_and_go_to_result_stage(self):

        self.timer.stop()

        self.number_indicator.hide()
        self.btn_square.hide()
        self.btn_start_stop.hide()

        self.main_vbox.removeWidget(self.number_indicator)
        self.main_vbox.removeWidget(self.btn_square)
        self.main_vbox.removeWidget(self.btn_start_stop)

        self.clear_the_main_box_from_stretch_and_space()

        self.go_to_result_stage()

    def rounding_func(self, numObj, digits=3):
        """Обрезает знаки за запятой"""
        return f"{numObj:.{digits}f}"

    def back_to_main_window(self):
        """Скрывает все элементы из окна с результатами и возвращается на главное окно"""

        self.table.hide()
        self.graph_of_results.hide()
        self.btn_go_to_main_menu.hide()
        self.btn_import.hide()
        self.clear_the_main_box_from_stretch_and_space()

        self.main_stage()

    def fill_in_the_table(self):
        list_of_table_column_names = [
            'Количество попыток', 'Лучший результат',
            'Номера попыток с лучшим результатом', 'Хуший результат',
            'Номера попыток с худшим результатом', 'Количество фальстартов',
            'Номера попыток с фальстартами', 'Средний результат'
        ]

        for element in list_of_table_column_names:
            column_name = QtGui.QStandardItem(element)
            self.model.setItem(0, self.counter_for_tries_for_table,
                               column_name)
            self.counter_for_tries_for_table += 1

        self.table.resizeRowsToContents()

        self.model.setItem(1, 0, QtGui.QStandardItem(str(self.count_of_try)))

        self.model.setItem(
            1, 1, QtGui.QStandardItem(str(min(self.list_of_reaction_times))))
        list_of_best_tries = []
        for elem in self.list_of_dicts_reaction_times_num_of_try:
            if elem[list(elem)[0]] == min(self.list_of_reaction_times):
                list_of_best_tries.append(list(elem)[0])
        string_of_best_tries = ''
        for num in list_of_best_tries:
            string_of_best_tries += str(num) + ', '
        self.model.setItem(1, 2,
                           QtGui.QStandardItem(str(string_of_best_tries)))

        self.model.setItem(
            1, 3, QtGui.QStandardItem(str(max(self.list_of_reaction_times))))
        list_of_worst_tries = []
        for elem in self.list_of_dicts_reaction_times_num_of_try:
            if elem[list(elem)[0]] == max(self.list_of_reaction_times):
                list_of_worst_tries.append(list(elem)[0])
        string_of_worst_tries = ''
        for num in list_of_worst_tries:
            string_of_worst_tries += str(num) + ', '
        self.model.setItem(1, 4,
                           QtGui.QStandardItem(str(string_of_worst_tries)))

        self.model.setItem(
            1, 5, QtGui.QStandardItem(str(len(self.list_of_falstarts))))
        numbers_of_falstarts = ''
        for num in self.list_of_falstarts:
            numbers_of_falstarts += str(num) + ', '
        self.model.setItem(1, 6,
                           QtGui.QStandardItem(str(len(numbers_of_falstarts))))

        var_for_average_result = 0
        for elem in self.list_of_dicts_reaction_times_num_of_try:
            var_for_average_result += elem[list(elem)[0]]
        average_result = var_for_average_result / len(
            self.list_of_dicts_reaction_times_num_of_try)

        self.model.setItem(
            1, 7, QtGui.QStandardItem(str(self.rounding_func(average_result))))

    def show_result_elements(self):
        self.table.show()
        self.result_stage_vbox.addWidget(self.table,
                                         alignment=QtCore.Qt.AlignTop
                                         | QtCore.Qt.AlignHCenter)
        self.result_stage_vbox.addStretch(1)

        #Создаёт график потому что это не Qt элемент и ему нужно перерисовываться
        self.graph_of_results = PlotCanvas(
            self,
            width=10,
            height=5,
            data_for_graph=self.list_of_dicts_reaction_times_num_of_try)
        self.result_stage_vbox.addWidget(self.graph_of_results,
                                         alignment=QtCore.Qt.AlignTop
                                         | QtCore.Qt.AlignHCenter)

        self.result_stage_vbox.addStretch(1)

        self.btn_go_to_main_menu.show()
        self.result_stage_hbox.addWidget(self.btn_go_to_main_menu)
        self.result_stage_hbox.addStretch(1)

        self.btn_import.show()
        self.result_stage_hbox.addWidget(self.btn_import)
        self.result_stage_hbox.addStretch(1)

        self.result_stage_hbox.addSpacing(200)
        self.result_stage_vbox.addLayout(self.result_stage_hbox)

    def create_result_elements(self):
        self.table = QtWidgets.QTableView()
        self.table.setFixedSize(819, 138)
        self.model = QtGui.QStandardItemModel(2, 8)
        self.table.setModel(self.model)

        self.result_stage_vbox.addWidget(self.table,
                                         alignment=QtCore.Qt.AlignTop
                                         | QtCore.Qt.AlignHCenter)
        self.result_stage_vbox.addStretch(1)

        self.graph_of_results = PlotCanvas(
            self,
            width=10,
            height=5,
            data_for_graph=self.list_of_dicts_reaction_times_num_of_try)
        self.result_stage_vbox.addWidget(self.graph_of_results,
                                         alignment=QtCore.Qt.AlignTop
                                         | QtCore.Qt.AlignHCenter)

        self.result_stage_vbox.addStretch(1)

        self.btn_go_to_main_menu = QtWidgets.QPushButton(
            'Вернуться на главное меню')
        self.btn_go_to_main_menu.setFixedSize(200, 50)
        self.btn_go_to_main_menu.clicked.connect(self.back_to_main_window)
        self.result_stage_hbox.addWidget(self.btn_go_to_main_menu)
        self.result_stage_hbox.addStretch(1)

        self.btn_import = QtWidgets.QPushButton('Импорт')
        self.btn_import.setFixedSize(100, 50)
        self.btn_import.clicked.connect(self.create_csv_table)
        self.result_stage_hbox.addWidget(self.btn_import)
        self.result_stage_hbox.addStretch(1)

        self.result_stage_hbox.addSpacing(200)
        self.result_stage_vbox.addLayout(self.result_stage_hbox)

    def go_to_result_stage(self):
        """Создаёт финальное окно результатов"""

        if bool(self.list_of_reaction_times) == False:
            self.main_stage()
            return

        self.counter_for_tries_for_table = 0

        self.result_stage_vbox = QtWidgets.QVBoxLayout()
        self.result_stage_hbox = QtWidgets.QHBoxLayout()

        if self.result_elements_created == True:
            self.show_result_elements()
        elif self.result_elements_created == False:
            self.create_result_elements()

        self.fill_in_the_table()

        self.main_vbox.addLayout(self.result_stage_vbox)

    def display(self):
        """Отвечает за обновление дисплея таймера"""
        self.number_indicator.display("%02d:%02d" % (self.sec, self.ms))
        if self.ms != 99:
            self.ms += 1
        else:
            self.ms = 0
            if self.sec != 59:
                self.sec += 1

    def background_color_window(self):
        """Создаёт окно и позволяет выбрать и обновить цвет фона"""
        background_color = QtWidgets.QColorDialog.getColor(
            parent=self, title='Выбор цвета фона')
        if background_color.isValid():
            palette = self.palette()
            palette.setColor(QtGui.QPalette.Normal, QtGui.QPalette.Background,
                             background_color)
            palette.setColor(QtGui.QPalette.Inactive,
                             QtGui.QPalette.Background, background_color)
            self.setPalette(palette)

    def square_color_window(self):
        """Создаёт окно и позволяет выбрать и обновить цвет квадрата"""
        self.square_color_before_change = QtWidgets.QColorDialog.getColor(
            parent=self, title='Выбор цвета квадрата')
        if self.square_color_before_change.isValid():
            palette = self.palette()
            palette.setColor(QtGui.QPalette.Button,
                             self.square_color_before_change)
            self.btn_square.setPalette(palette)
            self.btn_square.update()

    def square_after_change_color_window(self):
        """Создаёт окно и позволяет выбрать и обновить цвет квадрата после смены цвета"""
        color_after_change = QtWidgets.QColorDialog.getColor(
            parent=self, title='Выбор цвета квадрата')
        if color_after_change.isValid():
            self.square_color_after_change = color_after_change
            palette = self.palette()
            palette.setColor(QtGui.QPalette.Button,
                             self.square_color_after_change)
            self.btn_square.setPalette(palette)
            self.btn_square.update()

    def change_square_settings_color_before(self):
        """Красит квадрат в цвет до смены цвета"""
        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button,
                         self.square_color_before_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()

    def change_square_settings_color_after(self):
        """Красит квадрат в цвет после смены цвета"""
        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button, self.square_color_after_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()

    def open_music_file(self):
        """Открывает окно для выбора музыкального файла"""
        file = QtWidgets.QFileDialog.getOpenFileUrl(
            parent=self,
            caption="Выберите звуковой файл",
            filter="Звуковые файлы (*.mp3 *.ac3)")

        self.music_player.setMedia(QtMultimedia.QMediaContent(file[0]))

        if self.btn_play_music.isHidden():
            self.btn_play_music.show()

        with open(
                'config.json',
                'w',
                encoding="utf-8",
        ) as config_file:
            config_file.write(file[0].toString())

    def go_to_main_stage_from_setting(self):
        self.btn_go_back.hide()
        self.btn_background_color_settings.hide()
        self.btn_square_color_settings.hide()
        self.btn_square.hide()
        self.sound_option_text.hide()
        self.sound_checkbox.hide()
        self.btn_square_after_change_color_settings.hide()
        self.btn_square_color_before_change_color.hide()
        self.btn_square_color_after_change_color.hide()
        self.btn_open_music.hide()
        self.label_music_status.hide()
        self.btn_play_music.hide()
        self.main_stage()

    def show_settings_elements(self):
        self.btn_go_back.show()
        self.settings_hbox_1.addWidget(self.btn_go_back,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignLeft)

        self.btn_background_color_settings.show()
        self.settings_hbox_1.addWidget(self.btn_background_color_settings,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignLeft)

        self.btn_square_color_settings.show()
        self.settings_hbox_1.addWidget(self.btn_square_color_settings,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignLeft)

        self.btn_square_after_change_color_settings.show()
        self.settings_hbox_1.addWidget(
            self.btn_square_after_change_color_settings,
            alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
        self.settings_hbox_1.addStretch(1)

        self.btn_square_color_before_change_color.show()
        self.settings_hbox_1.addWidget(
            self.btn_square_color_before_change_color,
            alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignRight)

        self.btn_square_color_after_change_color.show()
        self.settings_hbox_1.addWidget(
            self.btn_square_color_after_change_color,
            alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignRight)
        self.settings_vbox_1.addLayout(self.settings_hbox_1)

        self.btn_square.show()
        self.settings_vbox_1.addStretch(1)
        self.settings_vbox_1.addWidget(self.btn_square,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignHCenter)
        self.settings_vbox_1.addStretch(1)

        self.btn_open_music.show()
        self.settings_hbox_2.addWidget(self.btn_open_music)
        self.settings_hbox_2.addStretch(1)

        self.label_music_status.show()
        self.settings_hbox_2.addWidget(self.label_music_status)
        self.settings_hbox_2.addStretch(1)

        self.btn_play_music.show()
        self.settings_hbox_2.addWidget(self.btn_play_music)
        self.settings_hbox_2.addStretch(1)

        self.sound_option_text.show()
        self.settings_hbox_2.addWidget(self.sound_option_text)

        self.sound_checkbox.show()
        self.settings_hbox_2.addWidget(self.sound_checkbox)
        self.settings_hbox_2.addStretch(1)

        self.settings_vbox_1.addLayout(self.settings_hbox_2)
        self.main_vbox.addLayout(self.settings_vbox_1)

    def create_settings_elemens(self):
        self.btn_go_back = QtWidgets.QPushButton('Назад', self)
        self.btn_go_back.setFixedSize(50, 50)
        self.btn_go_back.clicked.connect(self.go_to_main_stage_from_setting)
        self.settings_hbox_1.addWidget(self.btn_go_back,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignLeft)

        self.btn_background_color_settings = QtWidgets.QPushButton(
            'Цвет фона', self)
        self.btn_background_color_settings.setFixedSize(100, 50)
        self.btn_background_color_settings.clicked.connect(
            self.background_color_window)
        self.settings_hbox_1.addWidget(self.btn_background_color_settings,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignLeft)

        self.btn_square_color_settings = QtWidgets.QPushButton(
            'Цвет квадрата до смены цвета', self)
        self.btn_square_color_settings.setFixedSize(250, 50)
        self.btn_square_color_settings.clicked.connect(
            self.square_color_window)
        self.settings_hbox_1.addWidget(self.btn_square_color_settings,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignLeft)

        self.btn_square_after_change_color_settings = QtWidgets.QPushButton(
            'Цвет квадрата после смены цвета', self)
        self.btn_square_after_change_color_settings.setFixedSize(250, 50)
        self.btn_square_after_change_color_settings.clicked.connect(
            self.square_after_change_color_window)
        self.settings_hbox_1.addWidget(
            self.btn_square_after_change_color_settings,
            alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
        self.settings_hbox_1.addStretch(1)

        self.btn_square_color_before_change_color = QtWidgets.QPushButton(
            'Квадрат до смены цвета', self)
        self.btn_square_color_before_change_color.setFixedSize(200, 50)
        self.btn_square_color_before_change_color.clicked.connect(
            self.change_square_settings_color_before)
        self.settings_hbox_1.addWidget(
            self.btn_square_color_before_change_color,
            alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignRight)

        self.btn_square_color_after_change_color = QtWidgets.QPushButton(
            'Квадрат после смены цвета', self)
        self.btn_square_color_after_change_color.setFixedSize(200, 50)
        self.btn_square_color_after_change_color.clicked.connect(
            self.change_square_settings_color_after)
        self.settings_hbox_1.addWidget(
            self.btn_square_color_after_change_color,
            alignment=QtCore.Qt.AlignTop | QtCore.Qt.AlignRight)
        self.settings_vbox_1.addLayout(self.settings_hbox_1)

        self.btn_square = QtWidgets.QPushButton(' ', self)
        self.btn_square.setAutoFillBackground(True)
        self.btn_square.setFixedSize(
            500, 500)  # установить 2 переменные для настроек размера
        palette = self.palette()
        palette.setColor(QtGui.QPalette.Button,
                         self.square_color_before_change)
        self.btn_square.setPalette(palette)
        self.btn_square.update()
        self.settings_vbox_1.addStretch(1)
        self.settings_vbox_1.addWidget(self.btn_square,
                                       alignment=QtCore.Qt.AlignTop
                                       | QtCore.Qt.AlignHCenter)
        self.settings_vbox_1.addStretch(1)

        self.btn_open_music = QtWidgets.QPushButton("&Открыть файл...")
        self.btn_open_music.clicked.connect(self.open_music_file)
        self.settings_hbox_2.addWidget(self.btn_open_music)
        self.settings_hbox_2.addStretch(1)

        self.label_music_status = QtWidgets.QLabel('')
        self.label_music_status.hide()
        self.settings_hbox_2.addWidget(self.label_music_status)
        self.settings_hbox_2.addStretch(1)

        self.btn_play_music = QtWidgets.QPushButton('Прослушать')
        self.btn_play_music.clicked.connect(self.music_player.play)
        self.btn_play_music.hide()
        self.settings_hbox_2.addWidget(self.btn_play_music)
        self.settings_hbox_2.addStretch(1)

        self.sound_option_text = QtWidgets.QLabel("Наличие звукового сигнала")
        font_obj_for_label = QtGui.QFont('Segoe UI', pointSize=30)
        self.sound_option_text.setFont(font_obj_for_label)
        self.sound_option_text.show()
        self.settings_hbox_2.addWidget(self.sound_option_text)

        self.sound_checkbox = QtWidgets.QCheckBox(self)
        self.settings_hbox_2.addWidget(self.sound_checkbox)
        self.settings_hbox_2.addStretch(1)

        self.settings_vbox_1.addLayout(self.settings_hbox_2)
        self.main_vbox.addLayout(self.settings_vbox_1)

        self.settigs_elements_created = True

    def go_to_settings_stage(self):
        """Открывает окно настроек, создаёт все кнопки и всё там делает"""

        self.settings_hbox_1 = QtWidgets.QHBoxLayout()
        self.settings_vbox_1 = QtWidgets.QVBoxLayout()
        self.settings_hbox_2 = QtWidgets.QHBoxLayout()

        if self.settigs_elements_created == True:
            self.show_settings_elements()
        elif self.settigs_elements_created == False:
            self.create_settings_elemens()

        try:
            with open(
                    'config.json',
                    'r',
                    encoding="utf-8",
            ) as config_file:
                self.path_to_the_installed_music = config_file.read()

            self.music_player.setMedia(
                QtMultimedia.QMediaContent(
                    QtCore.QUrl(self.path_to_the_installed_music)))
            self.label_music_status.setText('Звук установлен')
            self.label_music_status.show()
            self.btn_play_music.show()
        except:
            self.label_music_status.setText('Звук не установлен')
            self.label_music_status.show()

    def clear_the_main_box_from_stretch_and_space(self):

        for i in range(self.main_vbox.count()):
            layout_item = self.main_vbox.itemAt(i)
            print(layout_item)
            if layout_item.layout() is not None:
                self.main_vbox.removeItem(layout_item)

    def go_to_test_stage_from_main_stage(self):

        self.title.hide()
        self.btn_start_test.hide()
        self.btn_settings.hide()

        self.main_vbox.removeWidget(self.title)
        self.main_vbox.removeWidget(self.btn_start_test)
        self.main_vbox.removeWidget(self.btn_settings)

        self.clear_the_main_box_from_stretch_and_space()

        self.go_to_test_stage()

    def go_to_settings_stage_from_main_stage(self):

        self.title.hide()
        self.btn_start_test.hide()
        self.btn_settings.hide()

        self.main_vbox.removeWidget(self.title)
        self.main_vbox.removeWidget(self.btn_start_test)
        self.main_vbox.removeWidget(self.btn_settings)

        self.clear_the_main_box_from_stretch_and_space()

        self.go_to_settings_stage()

    def create_main_stage_elements(self):

        self.title = QtWidgets.QLabel("Оценка скорости реакции", self)
        font_obj_for_label = QtGui.QFont('Segoe UI', pointSize=50)
        self.title.setFont(font_obj_for_label)
        self.main_vbox.addWidget(self.title,
                                 alignment=QtCore.Qt.AlignTop
                                 | QtCore.Qt.AlignHCenter)

        self.btn_start_test = QtWidgets.QPushButton('Тест', self)
        self.btn_start_test.setFixedSize(300, 50)
        self.btn_start_test.clicked.connect(
            self.go_to_test_stage_from_main_stage)
        self.main_vbox.addWidget(self.btn_start_test,
                                 alignment=QtCore.Qt.AlignTop
                                 | QtCore.Qt.AlignCenter)

        self.btn_settings = QtWidgets.QPushButton('Настройки', self)
        self.btn_settings.setFixedSize(300, 50)
        self.btn_settings.clicked.connect(
            self.go_to_settings_stage_from_main_stage)
        self.main_vbox.addWidget(self.btn_settings,
                                 alignment=QtCore.Qt.AlignTop
                                 | QtCore.Qt.AlignCenter)

        self.settings_elements_created = True

    def show_main_stage_elements(self):
        self.title.show()
        self.main_vbox.addWidget(self.title,
                                 alignment=QtCore.Qt.AlignTop
                                 | QtCore.Qt.AlignHCenter)

        self.btn_start_test.show()
        self.main_vbox.addWidget(self.btn_start_test,
                                 alignment=QtCore.Qt.AlignTop
                                 | QtCore.Qt.AlignCenter)

        self.btn_settings.show()
        self.main_vbox.addWidget(self.btn_settings,
                                 alignment=QtCore.Qt.AlignTop
                                 | QtCore.Qt.AlignCenter)

    def main_stage(self):
        """Создаёт главное окно"""
        self.clear_the_main_box_from_stretch_and_space()

        if self.main_elements_created == True:
            self.show_main_stage_elements()
        elif self.main_elements_created == False:
            self.create_main_stage_elements()

    def create_csv_table(self):

        with open('result_table.csv', "w", newline='') as csv_file:
            writer = csv.writer(csv_file, delimiter=',')
            count_num_and_try_time = []
            for element in self.list_of_dicts_reaction_times_num_of_try:
                count_num_and_try_time.append(
                    [list(element)[0], element[list(element)[0]]])
            for element in count_num_and_try_time:
                writer.writerow(element)
Ejemplo n.º 9
0
class DedeNimeur(QMainWindow):
    def __init__(self):
        super(DedeNimeur, self).__init__()
        self.statusBar()

        self.size, self.height, self.width, self.mines = 30, 10, 10, 10
        self.lcd = QLCDNumber()
        self.lcd.setFixedSize(300, 60)
        self.board = Board(self.height, self.width, self.mines, self.size)
        self.timer = QBasicTimer()
        self.real_timer = QElapsedTimer()

        vbox = QVBoxLayout()
        vbox.addWidget(self.lcd)
        vbox.addWidget(self.board)

        central = QWidget()
        central.setLayout(vbox)
        self.setCentralWidget(central)

        start = QAction('Start', self)
        start.setStatusTip('Start')
        start.setShortcut('Ctrl+N')
        start.triggered.connect(self.init)

        exit = QAction('Exit', self)
        exit.setStatusTip('Exit')
        exit.setShortcut('Ctrl+Q')
        exit.triggered.connect(qApp.quit)

        height = QAction('Height', self)
        height.setStatusTip('Set board width')
        height.triggered.connect(self.set_height)
        width = QAction('Width', self)
        width.setStatusTip('Set board height')
        width.triggered.connect(self.set_width)
        mines = QAction('Mines', self)
        mines.setStatusTip('Set board mines')
        mines.triggered.connect(self.set_mines)
        size = QAction('Size', self)
        size.setStatusTip('Set button size')
        size.triggered.connect(self.set_size)

        toolbar = self.addToolBar('Toolbar')
        toolbar.addAction(start)
        toolbar.addAction(width)
        toolbar.addAction(height)
        toolbar.addAction(mines)
        toolbar.addAction(size)
        toolbar.addAction(exit)

        self.setWindowTitle(u'DédéNimeur')
        self.show()

    def init(self):
        if self.mines < self.height * self.width:
            self.board.height = self.height
            self.board.width = self.width
            self.board.mines = self.mines
            self.board.size = self.size
            self.board.init()
        else:
            QMessageBox.question(self, 'NOPE', u"Va falloir spécifier un truc cohérent…", QMessageBox.Ok)

    def set_height(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'height')
        if ok:
            self.height = int(text)
            self.init()

    def set_width(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'width')
        if ok:
            self.width = int(text)
            self.init()

    def set_mines(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'mines')
        if ok:
            self.mines = int(text)
            self.init()

    def set_size(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'size')
        if ok:
            self.size = int(text)
            self.init()

    def start_timers(self):
        self.timer.start(100, self)
        self.real_timer.start()
        self.lcd.display(int(self.real_timer.elapsed() / 1000))

    def stop_timers(self):
        self.timer.stop()
        return self.real_timer.elapsed()

    def timerEvent(self, e):
        self.lcd.display(int(self.real_timer.elapsed() / 1000))
Ejemplo n.º 10
0
class Tetrixs(QWidget):
    def __init__(self):
        super(Tetrixs, self).__init__()
        self.initUI()

    def initUI(self):
        #窗口大小固定
        size = self.centerRect(tetrixsWidth, tetrixsHeight)
        self.setGeometry(size)
        self.setWindowTitle('Tetrixs')

        #设置背景色
        self.setStyleSheet(mainWindowColor)


        #LCD和Button
        self.levelNumber = QLCDNumber(self)
        self.scoreNumber = QLCDNumber(self)

        #设置初始值
        self.levelNumber.display(0)
        self.scoreNumber.display(0)

        self.pauseButton = QPushButton('PAUSE', self)
        self.startButton = QPushButton('START', self)

        #设置两个按钮无焦点
        self.pauseButton.setFocusPolicy(Qt.NoFocus)
        self.startButton.setFocusPolicy(Qt.NoFocus)

        #self.setFocusPolicy(Qt.StrongFocus)
        #self.startButton.set

        self.levelNumber.setFixedSize(150, 100)
        self.scoreNumber.setFixedSize(150, 100)
        self.pauseButton.setFixedSize(150, 100)
        self.startButton.setFixedSize(150, 100)

        self.levelNumber.setStyleSheet(lcdNumberColor)
        self.scoreNumber.setStyleSheet(lcdNumberColor)
        self.pauseButton.setStyleSheet(buttonColor)
        self.startButton.setStyleSheet(buttonColor)

        ##LCD和Button绑定action函数
        self.startButton.clicked.connect(self.startButtonAction)
        self.pauseButton.clicked.connect(self.pauseButtonAction)


        vLayout = QVBoxLayout()
        vLayout.addWidget(self.levelNumber)
        vLayout.addWidget(self.scoreNumber)
        vLayout.addWidget(self.pauseButton)
        vLayout.addWidget(self.startButton)

         #画布
        self.canvas = Canvas()
        self.canvas.setFixedSize(500, 800)

        self.canvas.getScoreSignal.connect(self.getScoreAction)
        self.canvas.gameOverSignal.connect(self.gameOverAction)

        hLayout = QHBoxLayout()
        hLayout.addWidget(self.canvas)
        hLayout.addLayout(vLayout)
        
        self.setLayout(hLayout)
        self.setFixedSize(tetrixsWidth, tetrixsHeight)
        self.show()

    def centerRect(self, width, height):
        screen = QGuiApplication.primaryScreen()
        screenWidth = screen.geometry().width()
        screenHeight = screen.geometry().height()
        centerWidth, centerHeight = screenWidth // 2, screenHeight // 2
        startWidth, startHeight = centerWidth - width // 2, centerHeight - height // 2

        return QRect(startWidth , startHeight, width, height)  

    def keyPressEvent(self, event):
        #向左旋转
        if event.key() == Qt.Key_Up:
            self.canvas.rotateLeft()

        #向右旋转
        if event.key() == Qt.Key_Down:
            self.canvas.rotateRight()

        #向左移动
        if event.key() == Qt.Key_Left:
            self.canvas.moveLeft()
            

        #向右移动
        if event.key() == Qt.Key_Right:
            self.canvas.moveRight()

        if event.key() == Qt.Key_Space:
            self.canvas.downDirect()
            

    def startButtonAction(self):
        #设置初始值
        self.levelNumber.display(0)
        self.scoreNumber.display(0)

        self.canvas.start()

    def pauseButtonAction(self):
        self.canvas.pause()
        if self.pauseButton.text() == "PAUSE":
            self.pauseButton.setText("CONTINUE")
        else:
            self.pauseButton.setText("PAUSE")


    def getScoreAction(self, score):

        QApplication.beep()

        value = self.scoreNumber.intValue()

        newValue = value + score

        self.scoreNumber.display(newValue)

        #更新speed
        if value / levelStep != newValue / levelStep:
            self.levelNumber.display(newValue / levelStep)
            self.canvas.speed *= percent

    def gameOverAction(self):
        self.msg()

    def msg(self):
        reply = QMessageBox.information(self, "Tetrixs", "GameOver", QMessageBox.Yes | QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.canvas.start()

        if reply == QMessageBox.No:
            app = QApplication(sys.argv)
            app.exit(0)
Ejemplo n.º 11
0
class DedeNimeur(QMainWindow):
    def __init__(self):
        super(DedeNimeur, self).__init__()
        self.statusBar()

        self.size, self.height, self.width, self.mines = 30, 10, 10, 10
        self.lcd = QLCDNumber()
        self.lcd.setFixedSize(300, 60)
        self.board = Board(self.height, self.width, self.mines, self.size)
        self.timer = QBasicTimer()
        self.real_timer = QElapsedTimer()

        vbox = QVBoxLayout()
        vbox.addWidget(self.lcd)
        vbox.addWidget(self.board)

        central = QWidget()
        central.setLayout(vbox)
        self.setCentralWidget(central)

        start = QAction('Start', self)
        start.setStatusTip('Start')
        start.setShortcut('Ctrl+N')
        start.triggered.connect(self.init)

        exit = QAction('Exit', self)
        exit.setStatusTip('Exit')
        exit.setShortcut('Ctrl+Q')
        exit.triggered.connect(qApp.quit)

        height = QAction('Height', self)
        height.setStatusTip('Set board width')
        height.triggered.connect(self.set_height)
        width = QAction('Width', self)
        width.setStatusTip('Set board height')
        width.triggered.connect(self.set_width)
        mines = QAction('Mines', self)
        mines.setStatusTip('Set board mines')
        mines.triggered.connect(self.set_mines)
        size = QAction('Size', self)
        size.setStatusTip('Set button size')
        size.triggered.connect(self.set_size)

        toolbar = self.addToolBar('Toolbar')
        toolbar.addAction(start)
        toolbar.addAction(width)
        toolbar.addAction(height)
        toolbar.addAction(mines)
        toolbar.addAction(size)
        toolbar.addAction(exit)

        self.setWindowTitle(u'DédéNimeur')
        self.show()

    def init(self):
        if self.mines < self.height * self.width:
            self.board.height = self.height
            self.board.width = self.width
            self.board.mines = self.mines
            self.board.size = self.size
            self.board.init()
        else:
            QMessageBox.question(self, 'NOPE',
                                 u"Va falloir spécifier un truc cohérent…",
                                 QMessageBox.Ok)

    def set_height(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'height')
        if ok:
            self.height = int(text)
            self.init()

    def set_width(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'width')
        if ok:
            self.width = int(text)
            self.init()

    def set_mines(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'mines')
        if ok:
            self.mines = int(text)
            self.init()

    def set_size(self):
        text, ok = QInputDialog.getText(self, 'Settings', 'size')
        if ok:
            self.size = int(text)
            self.init()

    def start_timers(self):
        self.timer.start(100, self)
        self.real_timer.start()
        self.lcd.display(int(self.real_timer.elapsed() / 1000))

    def stop_timers(self):
        self.timer.stop()
        return self.real_timer.elapsed()

    def timerEvent(self, e):
        self.lcd.display(int(self.real_timer.elapsed() / 1000))
Ejemplo n.º 12
0
class GamePlayerWidget(QGroupBox):

    def __init__(self, nick, colour=None, parent=None):
        super(GamePlayerWidget, self).__init__(parent)
        self.player = nick
        self.pcolour = colour
        self.initUI()

    def initUI(self):
        #        self.setMinimumWidth(300)
        self.mainLayout = QHBoxLayout(self)
#         self.mainLayout.addStretch()
        self.scoreLCD = QLCDNumber(self)
        self.scoreLCD.setSegmentStyle(QLCDNumber.Flat)
        self.mainLayout.addWidget(self.scoreLCD)
        self.scoreLCD.setNumDigits(3)
        self.scoreLCD.setFixedSize(100, 60)
        self.scoreLCD.display(0)
        css = "QLCDNumber {{ color:rgb({},{},{});}}"
        self.scoreLCD.setStyleSheet(css.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))

        self.nameLabel = QLabel(self)
        self.nameLabel.setText(self.player)
        sh = ("QLabel {{ font-size: 32px; font-weight: "
              "bold; color:rgb({},{},{});}}")
        self.nameLabel.setStyleSheet(sh.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))
        self.mainLayout.addWidget(self.nameLabel)

        self.dealerPixmap = QtGui.QPixmap('icons/cards.png')
        self.nonDealerPixmap = QtGui.QPixmap()
        self.winnerPixmap = QtGui.QPixmap('icons/winner.png')

        self.iconlabel = IconLabel(self)
        self.iconlabel.setFixedSize(50, 50)
        self.iconlabel.setScaledContents(True)
        self.mainLayout.insertWidget(0, self.iconlabel)
#         self.mainLayout.addStretch()
        self.unsetDealer()

    def updateDisplay(self, points):
        if points >= 1000:
            self.scoreLCD.setNumDigits(4)
        self.scoreLCD.display(points)

    def setDealer(self): self.iconlabel.setPixmap(self.dealerPixmap)

    def unsetDealer(self): self.iconlabel.setPixmap(self.nonDealerPixmap)

    def setWinner(self): self.iconlabel.setPixmap(self.winnerPixmap)

    def setColour(self, colour):
        self.pcolour = colour
        css = "QLCDNumber {{ color:rgb({},{},{});}}"
        self.scoreLCD.setStyleSheet(css.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))
        sh = ("QLabel {{ font-size: 32px; font-weight: bold; "
              "color:rgb({},{},{});}}")
        self.nameLabel.setStyleSheet(sh.format(self.pcolour.red(),
                                               self.pcolour.green(),
                                               self.pcolour.blue()))
Ejemplo n.º 13
0
class Klotski(QMainWindow):
    def __init__(self,
                 maps: Dict[int, KLMap],
                 firstBoard: Optional[int] = None) -> None:
        QMainWindow.__init__(self)
        self.klmap = None  # type: Optional[KLMap]
        self.moves = 0
        self.move_list = []  # type: List[ Tuple[str, Tuple[int, int]]]
        self.move_index = -1
        self.mini_maps_dict = {}  # type: Dict[int, QPixmap]
        self.levels_by_id = maps

        self.init_misc_gui()

        self.board.load_tiles()
        self.board.sig_move.connect(self.move_tile)

        self.generate_mini_maps()

        self.board_chooser = KLBoardChooser(
            KlMinimapProvider(self.levels_by_id, self.mini_maps_dict), self)
        self.board_chooser.hide()

        # needs self.board
        self.init_menu()

        self.setWindowTitle("Klotski")
        self.title_label.setText("Klotski")
        if firstBoard:
            self.new_level(self.levels_by_id[int(firstBoard)])
            self.move_enabled = True
        else:
            self.new_level(self.levels_by_id[ID_SPLASH_SCREEN])
            self.move_enabled = False

    def init_misc_gui(self) -> None:
        w = QWidget(self)
        self.setCentralWidget(w)
        ly = QVBoxLayout()
        w.setLayout(ly)
        ly.setSpacing(10)

        self.title_label = QLabel("Klotski", w)
        ft = self.title_label.font()
        ft.setPointSize(20)
        self.title_label.setFont(ft)
        self.title_label.setAlignment(Qt.AlignCenter)
        self.title_label.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed))
        ly.addWidget(self.title_label)

        hb = QHBoxLayout()
        self.board = KLBoard(w)
        hb.addWidget(self.board)
        hb.setStretchFactor(self.board, 100)
        ly.addLayout(hb)

        # horizontal bottom hbox [ QLabel | QLcdNumber ]
        hb = QHBoxLayout()
        # hb.setSpacing( 5 )
        # hb.setMargin( 5 )
        ml = QLabel("Moves : ", w)
        ml.setFont(ft)
        ml.setAlignment(Qt.AlignRight)
        hb.addWidget(ml)

        self.move_lcd_nb = QLCDNumber(4, w)
        self.move_lcd_nb.adjustSize()
        self.move_lcd_nb.setFixedSize(self.move_lcd_nb.width(), 30)
        hb.addWidget(self.move_lcd_nb)
        # hb.setFixedHeight( hb.height() )
        ly.addLayout(hb)

        self.adjustSize()

    def generate_mini_maps(self) -> None:
        self.mini_maps_dict = {}
        for i in self.levels_by_id.keys():
            self.mini_maps_dict[i] = self.board.generate_mini_map(
                self.levels_by_id[i])

    def new_level(self, m: KLMap) -> None:
        '''Display a new map into the main window'''
        if m.name != NAME_SPLASH_SCREEN:
            # display the name of the board
            self.setWindowTitle("Klotski - " + m.name)
            self.title_label.setText(m.name)
        else:
            # display the splash screen
            self.setWindowTitle("Klotski")
            self.title_label.setText('')

        self.klmap = m
        w = max(m.w * TILE_SIZE + 10 + 40,
                self.title_label.sizeHint().width() + 20)
        h = (m.h * TILE_SIZE + 10 + 80 + self.title_label.sizeHint().height() +
             max(self.move_lcd_nb.sizeHint().height(),
                 self.title_label.sizeHint().height()))

        center = self.frameGeometry().center()
        self.resize(w, h)

        r = self.frameGeometry()
        r.moveCenter(center)

        desktop = QApplication.desktop()
        if r.x() + w > desktop.width() or r.x(
        ) < 0 or r.y() + h > desktop.height() or r.y() < 0:

            r.moveCenter(desktop.rect().center())

        if r.x() < 0:
            r.setX(0)
        if r.y() < 0:
            r.setY(0)
        if r.x() + w > desktop.width():
            r.setX(0)
            w = desktop.width() - 20 - r.x()
        if r.y() + h > desktop.height():
            r.setY(0)
            h = desktop.height() - 20 - r.y()

        self.move(r.topLeft())
        self.resize(w, h)

        self.reset()

    def choose_board(self) -> None:
        self.board_chooser.exec()
        board_id = self.board_chooser.result()

        if board_id in self.levels_by_id:
            self.new_level(self.levels_by_id[board_id])

    def init_menu(self) -> None:
        file_menu = QMenu('Game', self)
        file_menu.addAction("Boards", self.choose_board, Qt.CTRL + Qt.Key_B)
        file_menu.addAction("Quit", self.close,
                            Qt.CTRL + Qt.Key_X)  # type: ignore
        file_menu.addAction("About Klotski", self.about)

        move_menu = QMenu('Moves', self)
        move_menu.addAction("Reset", self.reset)
        move_menu.addAction("Undo", self.undo, Qt.CTRL + Qt.Key_U)
        move_menu.addAction("Redo", self.redo, Qt.CTRL + Qt.Key_R)

        main_menu = self.menuBar()
        main_menu.addMenu(file_menu)
        main_menu.addMenu(move_menu)

    def set_move_nb(self, m: int) -> None:
        self.move_lcd_nb.display(m)
        self.moves = m

    def move_tile(self, move_info: Tuple[str, Tuple[int, int]]) -> None:
        pid, delta = move_info
        if not self.move_enabled:
            return

        assert self.klmap
        self.klmap.move_piece(pid, delta)
        self.board.move_piece(pid, delta)

        if self.move_index < 0:
            self.move_list = [(pid, (0, 0))]
            self.move_index = 0
            self.set_move_nb(self.moves + 1)

        last_move_pid, last_move = self.move_list[self.move_index]

        if pid != last_move_pid:
            self.move_index = self.move_index + 1
            self.move_list[self.move_index:] = [(pid, delta)]
            self.set_move_nb(self.moves + 1)
        else:
            self.move_list[self.move_index:] = [
                (pid, (last_move[0] + delta[0], last_move[1] + delta[1]))
            ]

        if self.klmap.is_game_won():
            QMessageBox.information(
                self, "Congratulation",
                "Congratulations!!!\nYou completed this level in %d moves" %
                self.moves)
            self.move_enabled = False
            self.klmap.reset()

    def reset(self) -> None:
        assert self.klmap
        self.klmap.reset()
        self.board.set_map(self.klmap)
        self.set_move_nb(0)
        self.move_enabled = True
        self.move_list = []
        self.move_index = -1

    def undo(self) -> None:
        if self.move_index < 0:
            return
        if not self.move_enabled:
            return

        pid = self.move_list[self.move_index][0]
        d = reverse_move(self.move_list[self.move_index][1])
        assert self.klmap
        assert self.board
        self.klmap.move_piece(pid, d)
        self.board.move_piece(pid, d)
        self.set_move_nb(self.moves - 1)

        self.move_index = self.move_index - 1

    def redo(self) -> None:
        if self.move_index + 1 >= len(self.move_list):
            return
        if not self.move_enabled:
            return

        self.move_index = self.move_index + 1
        pid, d = self.move_list[self.move_index]
        assert self.klmap
        assert self.board
        self.klmap.move_piece(pid, d)
        self.board.move_piece(pid, d)
        self.set_move_nb(self.moves + 1)

    def about(self) -> None:
        QMessageBox.about(self, 'About Klotski', MSG_ABOUT)

    def print_state(self) -> None:
        print(self.klmap)
        print("Move list : ", self.move_list)
        print("move list index : ", self.move_index)
Ejemplo n.º 14
0
class Main(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        # number of calls - new game
        self.CH = 0

        # the game timer
        self.timer = QTimer()
        self.timer.timeout.connect(self.second_on_LSD)

        # the number of movies
        self.num_moves = 0
        # the second of game
        self.second = 0
        # number of times the radar-button is pressed
        self.num_radar = 3

        # The initial height of the playing field
        self.height_area = 9
        # The initial width of the playing field
        self.width_area = 9
        # Initial number of mines per field
        self.num_mines = 10

        # loading-flag
        self.loading = False

        # Creating a playing field
        self.createAll()

        # Creating a playing menu
        self.createMenu()

    # Creating playing field components
    def createAll(self):

        # New game or loaded from save?
        if not self.loading:
            # Filling the field with mines at the beginning of the game
            self.field = area(self.width_area, self.height_area,
                              self.num_mines)

        self.loading = False

        # The central widget
        self.mainWidget = QWidget(self)
        self.setCentralWidget(self.mainWidget)

        # The main layer
        self.main_vBox = QVBoxLayout(self.mainWidget)

        # The layer Info-Board
        self.hBox = QHBoxLayout()

        # Playing field layer
        self.grid = QGridLayout()

        # Top buttons (info-board)
        self.lcd_left = QLCDNumber()
        self.lcd_left.setFixedSize(QSize(100, 30))
        self.hBox.addWidget(self.lcd_left)

        self.smile_btn = QPushButton()
        self.smile_btn.setFixedSize(QSize(40, 40))
        self.smile_btn.setIconSize(QSize(40, 40))
        self.smile_btn.setIcon(QIcon('./images/smile.png'))
        self.smile_btn.setFlat(True)  # no frame
        self.smile_btn.clicked.connect(self.newGameAction)
        self.hBox.addWidget(self.smile_btn)

        self.lcd_right = QLCDNumber()
        self.lcd_right.setFixedSize(QSize(100, 30))
        self.hBox.addWidget(self.lcd_right)

        self.main_vBox.addLayout(self.hBox)

        # Playing field
        gbox = QGroupBox()
        gbox.setStyleSheet('background-color: white')

        # Adding a playing field
        self.gameArea()

        self.lcd_left.display(self.num_moves)
        self.lcd_right.display(self.second)

        gbox.setLayout(self.grid)
        self.main_vBox.addWidget(gbox)

        self.statusBar().showMessage('Go!')
        self.setLayout(self.main_vBox)

    # Creating a game menu
    def createMenu(self):
        # Menu Events - Game
        newGame = QAction('New game', self)
        newGame.setShortcut('Ctrl+N')
        newGame.triggered.connect(self.newGameAction)
        newGame.setStatusTip('Start a new game')

        saveGame = QAction('Save', self)
        saveGame.setShortcut('Ctrl+S')
        saveGame.triggered.connect(self.saveGameAction)
        saveGame.setStatusTip('Save current game')

        loadGame = QAction('Load', self)
        loadGame.setShortcut('Ctrl+D')
        loadGame.triggered.connect(self.loadGameAction)
        loadGame.setStatusTip('Load current game')

        statGame = QAction('Statistics', self)
        statGame.setShortcut('Ctrl+Z')
        statGame.triggered.connect(self.statGameAction)
        statGame.setStatusTip('View game statistics')

        exitGame = QAction('Quit', self)
        exitGame.setShortcut('Esc')
        exitGame.triggered.connect(self.close)
        exitGame.setStatusTip('Quit the game')

        # Menu Events - Difficulty
        newbieDiff = QAction('Newbie', self)
        newbieDiff.triggered.connect(self.newbieDiffAction)
        newbieDiff.setStatusTip('Field 9х9, 10 mines')

        amateurDiff = QAction('Amateur', self)
        amateurDiff.triggered.connect(self.amateurDiffAction)
        amateurDiff.setStatusTip('Field 16х16, 40 mines')

        profiDiff = QAction('Professional', self)
        profiDiff.triggered.connect(self.profiDiffAction)
        profiDiff.setStatusTip('Field 16х30, 99 mines')

        specialDiff = QAction('Special...', self)
        specialDiff.triggered.connect(self.specialDiffAction)
        specialDiff.setStatusTip('Of your choice')

        # Menu Events - Help
        helpHelp = QAction('Rules', self)
        helpHelp.triggered.connect(self.helpFunc)
        helpHelp.setStatusTip('Help')

        aboutHelp = QAction('About the program', self)
        aboutHelp.triggered.connect(self.aboutFunc)
        aboutHelp.setStatusTip('About the program')

        # Menu - Game
        self.menubar = self.menuBar()

        self.gameMenu = self.menubar.addMenu('Game')
        self.gameMenu.addAction(newGame)
        self.gameMenu.addAction(saveGame)
        self.gameMenu.addAction(loadGame)
        self.gameMenu.addAction(statGame)
        self.gameMenu.addAction(exitGame)

        # Menu - Difficulty
        self.diffMenu = self.menubar.addMenu('Difficulty')
        self.diffMenu.addAction(newbieDiff)
        self.diffMenu.addAction(amateurDiff)
        self.diffMenu.addAction(profiDiff)
        self.diffMenu.addAction(specialDiff)

        # Menu - Help
        self.helpMenu = self.menubar.addMenu('Help')
        self.helpMenu.addAction(helpHelp)
        self.helpMenu.addAction(aboutHelp)

    # New game
    def newGameAction(self):
        text = 'All gameplay will be reset without saving. Continue?'
        if self.num_moves > 0 and not self.loading or self.second > 0:
            self.timerFunc(stop=True)
            question = QMessageBox.question(self, 'Attention!', text,
                                            QMessageBox.Yes | QMessageBox.No,
                                            QMessageBox.No)
            if question == QMessageBox.Yes:
                # Zeroing the timer and the number of moves if "New game" is selected
                self.timerFunc(reset=True)
                self.createAll()
            else:
                self.timerFunc(pause=True)
        else:
            self.createAll()

    # Gambling field arrangement
    # Playing field tiles
    def gameArea(self):
        # List of game field buttons
        # to access the state of each button
        self.list_btns = []
        for x in range(self.height_area):
            row_btns = []
            for y in range(self.width_area):
                value = self.field[x][y]
                btn = Cell(x, y, value, self.smile_btn, self.timerFunc,
                           self.showMoves, self.checkBTN, self.usedFlag,
                           self.radar, self.changeValue, self)
                self.grid.addWidget(btn, x, y)
                row_btns.append(btn)
            self.list_btns.append(row_btns)

        # Window geometry
        if self.CH > 0:
            self.adjustSize()
        self.CH += 1

    # Change cell value
    def changeValue(self, value, x, y):
        self.field[x][y] = value

    # progress check
    def checkBTN(self, left, x=None, y=None):
        # left mouse button
        if left:
            self.showMoves()
            # mine?
            if self.field[x][y] == 19:
                self.win = False
                self.gameOver()
            elif self.field[x][y] == 10:
                # List of cells around the pressed button
                self.open_lst = []
                self.openBTN(x, y)
                # Opening empty cells
                for k in self.open_lst:
                    k.is_open = True
                    k.update()
        # right mouse button
        else:
            flag_on_mine = 0
            for i in range(self.height_area):
                for j in range(self.width_area):
                    if self.field[i][j] == 29:
                        flag_on_mine += 1
            # If all the flags on all mines - victory!
            if flag_on_mine == self.num_mines:
                self.win = True
                self.gameOver()

    # Count remaining flags
    def usedFlag(self):
        flag = 0
        for row in self.field:
            for value in row:
                if 19 < value < 30:
                    flag += 1

        if flag < self.num_mines:
            self.showMoves()
            return True
        else:
            return False

    # Game End Check
    def gameOver(self):
        self.game_over = True
        # Win or lose to record statistics
        if self.win:
            winner = 'victory'
        else:
            winner = 'losing'

        # Saving game results
        size = str(self.height_area) + 'x' + str(self.width_area)
        saveResult(size, str(self.num_mines), str(self.num_moves),
                   str(self.second), winner)

        self.timerFunc(stop=True)
        # The result of the dialogue - the end of the game - New game or exit
        self.new_exit = False
        dialog = Over(self)
        dialog.exec_()
        # Processing the result of the dialog "End of the game"
        if self.new_exit:
            # Selected option - new game
            self.timerFunc(reset=True)
            self.newGameAction()
        else:
            # Closing the main program window, ending the game
            self.close()

    # Recursive search for empty cells
    def openBTN(self, x, y):
        if self.field[x][y] == 10 or self.field[x][y] == 0:
            for i in range(x - 1, x + 2):
                for j in range(y - 1, y + 2):
                    if 0 <= i < self.height_area and 0 <= j < self.width_area and self.field[
                            i][j] < 9:
                        if self.list_btns[i][j] not in self.open_lst:
                            self.open_lst.append(self.list_btns[i][j])
                            self.field[i][j] += 10
                            self.openBTN(i, j)

    # Method for calculating game time and resetting parameters
    def timerFunc(self, start=False, stop=False, pause=False, reset=False):
        if start and self.num_moves == 0:
            self.timer.start(1000)
        elif stop:
            self.timer.stop()
            stop = False
        elif pause:
            self.timer.start()
            pause = False
        elif reset:
            # Zeroing the number of moves
            self.num_moves = 0
            # Zeroing the number of flags on the field
            self.used_flag = 0

            # Setting the radar value if "new game"
            if self.second > 0 and not self.loading:
                if self.num_mines <= 10:
                    self.num_radar = 3
                elif 10 < self.num_mines <= 40:
                    self.num_radar = 10
                elif 40 < self.num_mines:
                    self.num_radar = 15

            # Timer reset
            self.second = 0
            # Reset reset
            reset = False

    # RADAR method - open (close) cells using RMB
    def radar(self, open, x=None, y=None):
        if self.num_radar > 0:
            if open:
                self.radar_btn = []
                for i in range(x - 1, x + 2):
                    for j in range(y - 1, y + 2):
                        if (0 <= i < self.height_area
                                and 0 <= j < self.width_area
                                and not self.list_btns[i][j].is_open
                                and not self.list_btns[i][j].is_flag):
                            self.radar_btn.append(self.list_btns[i][j])
                            self.list_btns[i][j].is_open = True
                            self.list_btns[i][j].update()
            else:
                for btn in self.radar_btn:
                    btn.is_open = False
                    btn.update()
                self.num_radar -= 1

    # Counting and displaying the number of moves
    def showMoves(self):
        self.num_moves += 1
        self.lcd_left.display(self.num_moves)

    # Game time display
    def second_on_LSD(self):
        self.second += 1
        self.lcd_right.display(self.second)

    def helpFunc(self):
        file = open('images/rules.txt')
        text = file.read()
        QMessageBox.information(self, 'Reference', text)

    def aboutFunc(self):
        QMessageBox.about(self, 'About programm', 'closed beta-vertion')

    # Save game method
    def saveGameAction(self):
        self.saveGameAction = Save(self.second, self.num_moves, self.num_radar,
                                   self.width_area, self.field, self)

    # Saved Game Load Method
    def loadGameAction(self):
        self.timerFunc(stop=True)
        dialog = Load(self)
        dialog.exec_()
        if self.loading:
            self.newGameAction()
        else:
            self.timerFunc(pause=True)

    # View game statistics
    def statGameAction(self):
        self.timerFunc(stop=True)
        dialog = Stat(self)
        dialog.exec_()
        self.timerFunc(pause=True)

    def newbieDiffAction(self):
        self.height_area = 9
        self.width_area = 9
        self.num_mines = 10
        self.num_radar = 3

        self.newGameAction()

    def amateurDiffAction(self):
        self.height_area = 16
        self.width_area = 16
        self.num_mines = 40
        self.num_radar = 10

        self.newGameAction()

    def profiDiffAction(self):
        self.height_area = 16
        self.width_area = 30
        self.num_mines = 99
        self.num_radar = 15

        self.newGameAction()

    # Calling up a menu item - Special parameters
    def specialDiffAction(self):
        # Stopping the timer during the dialogue with the user
        self.change = False
        self.timerFunc(stop=True)

        # Calling the window for changing the parameters and passing to its data class
        dialog = Size(self.height_area, self.width_area, self.num_mines, self)
        dialog.exec_()

        # If the user changed the game settings
        if self.change:
            self.newGameAction()
        else:
            self.timerFunc(pause=True)
Ejemplo n.º 15
0
class GeneralsTab(QWidget):
    def __init__(self, bus, bms_com):
        super().__init__()
        self.com1 = bms_com
        self.bus = bus
        '''self.warning_label = QLabel()
        warning_layout = QHBoxLayout()
        warning_layout.addStretch()
        warning_layout.addWidget(self.warning_label)
        warning_layout.addStretch()'''

        #set state of charge layout
        self.stateofcharge = QLabel('State of Charge:')
        self.percentage = QLabel('%')
        self.line = QLineEdit()
        #self.fillBlanks('soc', self.line)
        self.line.setFixedWidth(40)
        self.line.setReadOnly(True)

        self.logo = QLabel('')
        self.i = QPixmap('C:/Users/iheb/BMS_UI/icons/State of charge.ico')
        self.logo.setPixmap(self.i.scaled(30, 30))

        h_box0 = QHBoxLayout()
        h_box0.addSpacing(30)
        h_box0.addWidget(self.logo)
        h_box0.addWidget(self.stateofcharge)
        h_box0.addWidget(self.line)
        h_box0.addWidget(self.percentage)
        h_box0.addStretch()

        # set GeneralVolatge Layout

        self.voltage = QLabel("Battery Voltage")
        self.line2 = QLineEdit()

        self.line2.setFixedWidth(50)
        self.line2.setReadOnly(True)
        self.v = QLabel('V')

        self.logo1 = QLabel('')
        self.i1 = QPixmap('C:/Users/iheb/BMS_UI/icons/voltage.ico')
        self.logo1.setPixmap(self.i1.scaled(30, 30))

        h_box2 = QHBoxLayout()
        h_box2.addSpacing(30)
        h_box2.addWidget(self.logo1)
        h_box2.addWidget(self.voltage)
        h_box2.addWidget(self.line2)
        h_box2.addWidget(self.v)
        h_box2.addStretch()

        # set SC Layout

        self.sc = QLabel("Shutdown Circuit")
        self.line3 = QLineEdit()
        self.line3.setFixedWidth(50)
        self.line3.setReadOnly(True)

        self.logo2 = QLabel('')
        self.i2 = QPixmap('C:/Users/iheb/BMS_UI/icons/sc.png')
        self.logo2.setPixmap(self.i2.scaled(30, 30))

        h_box3 = QHBoxLayout()
        h_box3.addSpacing(30)
        h_box3.addWidget(self.logo2)
        h_box3.addWidget(self.sc)
        h_box3.addWidget(self.line3)

        h_box3.addStretch()

        #set Current (strom) layout
        self.current = QLabel("Battery Current (Strom)")
        self.line4 = QLineEdit()
        self.line4.setFixedWidth(50)
        self.line4.setReadOnly(True)
        self.c = QLabel('mA')

        self.logo3 = QLabel('')
        self.i3 = QPixmap('C:/Users/iheb/BMS_UI/icons/Strom.ico')
        self.logo3.setPixmap(self.i3.scaled(30, 30))

        h_box4 = QHBoxLayout()
        h_box4.addSpacing(30)
        h_box4.addWidget(self.logo3)
        h_box4.addWidget(self.current)
        h_box4.addWidget(self.line4)
        h_box4.addWidget(self.c)
        h_box4.addStretch()

        # first vertical layout that contains 5 horizental ones
        v_box1 = QVBoxLayout()
        v_box1.addSpacing(30)
        v_box1.addLayout(h_box0)

        v_box1.addStretch()

        v_box1.addLayout(h_box4)
        v_box1.addStretch()
        v_box1.addLayout(h_box2)

        v_box1.addStretch()
        v_box1.addLayout(h_box3)

        # max voltage layout

        self.vm = QLabel('Voltage Max:')
        self.line5 = QLineEdit()
        self.line5.setFixedWidth(50)
        self.line5.setReadOnly(True)
        self.logo8 = QLabel('')
        self.i8 = QPixmap('C:/Users/iheb/BMS_UI/icons/maxVoltage.png')
        self.logo8.setPixmap(self.i8.scaled(30, 30))
        self.v1 = QLabel('V')

        h_box5 = QHBoxLayout()
        h_box5.addSpacing(30)
        h_box5.addWidget(self.logo8)
        h_box5.addWidget(self.vm)
        h_box5.addWidget(self.line5)
        h_box5.addWidget(self.v1)
        h_box5.addStretch()

        # min Voltage Layout

        self.prStartTime = QLabel('Voltage Min:')
        self.line6 = QLineEdit()

        self.line6.setFixedWidth(50)
        self.line6.setReadOnly(True)
        self.logo4 = QLabel('')
        self.i4 = QPixmap('C:/Users/iheb/BMS_UI/icons/minVoltage.png')
        self.logo4.setPixmap(self.i4.scaled(30, 30))
        self.s = QLabel('mV')
        h_box6 = QHBoxLayout()
        h_box6.addSpacing(30)
        h_box6.addWidget(self.logo4)
        h_box6.addWidget(self.prStartTime)
        h_box6.addWidget(self.line6)
        h_box6.addWidget(self.s)
        h_box6.addStretch()

        # max temperature Layout

        self.failTime = QLabel('Temperature Max:')
        self.line7 = QLineEdit()
        self.line7.setFixedWidth(50)
        self.line7.setReadOnly(True)
        self.logo5 = QLabel('')
        self.i5 = QPixmap('C:/Users/iheb/BMS_UI/icons/maxTemperature.png')
        self.logo5.setPixmap(self.i5.scaled(30, 30))
        self.s1 = QLabel('C°')
        h_box7 = QHBoxLayout()
        h_box7.addSpacing(30)
        h_box7.addWidget(self.logo5)
        h_box7.addWidget(self.failTime)
        h_box7.addWidget(self.line7)
        h_box7.addWidget(self.s1)
        h_box7.addStretch()

        # min Temperature Layout

        self.upTime = QLabel('Temperature Min:')
        self.line8 = QLineEdit()
        self.line8.setFixedWidth(50)
        self.line8.setReadOnly(True)
        self.logo6 = QLabel('')
        self.i6 = QPixmap('C:/Users/iheb/BMS_UI/icons/minTemperature.png')
        self.logo6.setPixmap(self.i6.scaled(30, 30))
        self.s2 = QLabel('C°')
        h_box8 = QHBoxLayout()
        h_box8.addSpacing(30)
        h_box8.addWidget(self.logo6)
        h_box8.addWidget(self.upTime)
        h_box8.addWidget(self.line8)
        h_box8.addWidget(self.s2)
        h_box8.addStretch()

        # second vertical layout that contains 5 horizental ones
        v_box2 = QVBoxLayout()
        v_box2.addSpacing(30)
        v_box2.addLayout(h_box5)
        v_box2.addStretch()
        v_box2.addLayout(h_box6)
        v_box2.addStretch()
        v_box2.addLayout(h_box7)
        v_box2.addStretch()
        v_box2.addLayout(h_box8)

        #Transmition error Layout

        self.txError = QLabel('Transmition Error: ')
        self.line10 = QLineEdit()
        self.line10.setFixedWidth(50)
        self.line10.setReadOnly(True)

        h_box10 = QHBoxLayout()
        h_box10.addSpacing(30)
        h_box10.addWidget(self.txError)
        h_box10.addWidget(self.line10)
        h_box10.addStretch()

        # set current State layout

        self.state = QLabel("Current State: ")
        self.line1 = QLineEdit()
        self.line1.setFixedWidth(120)
        self.line1.setReadOnly(True)
        h_box1 = QHBoxLayout()
        h_box1.addSpacing(30)
        h_box1.addWidget(self.state)
        h_box1.addWidget(self.line1)
        h_box1.addStretch()

        # dcLink Voltage Layout

        self.HV_state = QLabel('HV Button:')
        self.line9 = QLineEdit('off')

        self.line9.setFixedWidth(30)
        self.line9.setReadOnly(True)
        self.v2 = QLabel('V')
        h_box9 = QHBoxLayout()
        h_box9.addSpacing(30)
        h_box9.addWidget(self.HV_state)
        h_box9.addWidget(self.line9)
        #h_box9.addWidget(self.v2)
        h_box9.addStretch()

        #start balancing command
        self.startBalancing = QPushButton('Start Balancing')
        self.logo7 = QLabel('')
        self.i7 = QPixmap('C:/Users/iheb/BMS_UI/icons/balancing.png')
        self.logo7.setPixmap(self.i7.scaled(30, 30))
        self.respond = QLabel('   ')

        #HV_Button_simuator
        self.HVButton = QPushButton('HV Button')
        self.logo9 = QLabel('')
        self.i9 = QPixmap('C:/Users/iheb/BMS_UI/icons/HV.png')
        self.logo9.setPixmap(self.i9.scaled(30, 30))
        self.respond1 = QLabel()
        self.i_hv = QPixmap('C:/Users/iheb/BMS_UI/icons/respond.png')

        h_box15 = QHBoxLayout()
        h_box15.addSpacing(30)
        h_box15.addWidget(self.logo7)
        h_box15.addSpacing(10)
        h_box15.addWidget(self.startBalancing)
        h_box15.addStretch()
        h_box15.addWidget(self.respond)
        h_box15.addStretch()

        h_box16 = QHBoxLayout()
        h_box16.addSpacing(30)
        h_box16.addWidget(self.logo9)
        h_box16.addSpacing(10)
        h_box16.addWidget(self.HVButton)
        h_box16.addStretch()
        h_box16.addWidget(self.respond1)
        h_box16.addStretch()

        v_box4 = QVBoxLayout()
        v_box4.addLayout(h_box15)
        v_box4.addStretch()
        v_box4.addLayout(h_box16)
        v_box4.addStretch()

        # AirLsAux  Layout
        '''self.airls = QLabel('AirLSAux: ')
        self.line11 = QLineEdit()
        self.line11.setFixedWidth(30)
        self.line11.setReadOnly(True)

        h_box11 = QHBoxLayout()
        h_box11.addSpacing(30)
        h_box11.addWidget(self.airls)
        h_box11.addWidget(self.line11)
        h_box11.addStretch()

        # AirHsAux  Layout

        self.airhs = QLabel('AirHSAux: ')
        self.line12 = QLineEdit()
        self.line12.setFixedWidth(30)
        self.line12.setReadOnly(True)

        h_box12 = QHBoxLayout()
        h_box12.addSpacing(30)
        h_box12.addWidget(self.airhs)
        h_box12.addWidget(self.line12)
        h_box12.addStretch()

        # HV Button  Layout

        self.hvButton = QLabel('HV Button: ')
        self.line13 = QLineEdit()
        self.line13.setFixedWidth(30)
        self.line13.setReadOnly(True)


        h_box13 = QHBoxLayout()
        h_box13.addSpacing(30)
        h_box13.addWidget(self.hvButton)
        h_box13.addWidget(self.line13)
        h_box13.addStretch()

        # Start Load Layout

        self.startLoad = QLabel('StartLoad: ')
        self.line14 = QLineEdit()
        self.line14.setFixedWidth(30)
        self.line14.setReadOnly(True)

        h_box14 = QHBoxLayout()
        h_box14.addSpacing(30)
        h_box14.addWidget(self.startLoad)
        h_box14.addWidget(self.line14)
        h_box14.addStretch()'''

        #third vertical layout that contains 5 horizental ones
        v_box3 = QVBoxLayout()
        v_box3.addSpacing(30)
        v_box3.addLayout(h_box10)
        v_box3.addStretch()
        v_box3.addLayout(h_box1)
        v_box3.addStretch()
        v_box3.addLayout(h_box9)
        v_box3.addStretch()
        v_box3.addLayout(v_box4)

        #horizental layout containing the fan controlling slider

        self.comment = QLabel('Enable')
        self.enable = QCheckBox()
        self.fan = QLabel('Fan Controller: ')
        self.lcd = QLCDNumber(self)
        self.sld = QSlider(Qt.Horizontal, self)
        self.sld.setMinimum(0)
        self.sld.setMaximum(100)
        self.sld.setTickInterval(1)
        palette = self.lcd.palette()
        palette.setColor(palette.Light, QColor(255, 0, 0))
        self.lcd.setPalette(palette)
        self.lcd.setFixedSize(55, 30)
        hbox = QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(self.comment)
        hbox.addWidget(self.enable)
        hbox.addWidget(self.fan)
        hbox.addWidget(self.sld)
        hbox.addSpacing(30)
        hbox.addWidget(self.lcd)
        hbox.addStretch()

        # set general layout
        v_box0 = QVBoxLayout()

        h_box = QHBoxLayout()
        h_box.addLayout(v_box1)
        h_box.addStretch()
        h_box.addLayout(v_box2)
        h_box.addStretch()
        h_box.addLayout(v_box3)
        h_box.addSpacing(30)
        #v_box0.addLayout(warning_layout)
        v_box0.addLayout(h_box)
        v_box0.addSpacing(30)

        v_box = QVBoxLayout()
        v_box.addLayout(v_box0)
        v_box.addLayout(hbox)

        self.setLayout(v_box)
        self.t = QTimer()  #timer for the Balancing response
        self.t1 = QTimer()  #timer for the HV Button response
        self.ie = QPixmap('C:/Users/iheb/BMS_UI/icons/error.png')
        self.i = QPixmap('C:/Users/iheb/BMS_UI/icons/respond.png')

    def fillBlanks(
        self
    ):  #methode that times the filling of the labels from the general tab
        self.timer1 = QTimer()
        self.timer1.timeout.connect(lambda: self.setData())
        self.timer1.start(2000)

    def setData(self):  #methode that enables the data to be set
        """self.d = self.data
        threading.Thread(target= self.d.fillData(140, 'soc')).start()
        threading.Thread(target=self.d.fillData(140, 'cs')).start()
        threading.Thread(target=self.d.fillData(140, 'bc')).start()
        threading.Thread(target=self.d.fillData(140, 'bv')).start()
        threading.Thread(target=self.d.fillData(140, 'sc')).start()
        threading.Thread(target=self.d.fillData(140, 'hvb')).start()
        threading.Thread(target=self.d.fillData(140, 'te')).start()
        threading.Thread(target=self.d.fillData(140, 'mxV')).start()
        threading.Thread(target=self.d.fillData(140, 'mnV')).start()
        threading.Thread(target=self.d.fillData(140, 'mxT')).start()
        threading.Thread(target=self.d.fillData(140, 'mnT')).start()"""
        self.line.setText(str(BMS_Data.getdata(cell=1, type='soc')))

        self.line1.setText(str(BMS_Data.getdata(cell=1, type='cs')))
        #print(str(BMS_Data.getdata(cell=1, type='cs')))
        self.line2.setText(str(BMS_Data.getdata(cell=1, type='bv')))
        #print(str(BMS_Data.getdata(cell=1, type='bv')))
        self.line3.setText(str(BMS_Data.getdata(cell=1, type='sc')))
        #print(str(BMS_Data.getdata(cell=1, type='sc')))
        self.line4.setText(str(BMS_Data.getdata(cell=1, type='bc')))
        #print(str(BMS_Data.getdata(cell=1, type='bc')))
        self.line5.setText(str(BMS_Data.getdata(cell=1, type='mxV')))
        #print(str(BMS_Data.getdata(cell=1, type='mxV')))
        self.line6.setText(str(BMS_Data.getdata(cell=1, type='mnV')))
        #print(str(BMS_Data.getdata(cell=1, type='mnV')))
        self.line7.setText(str(BMS_Data.getdata(cell=1, type='mxT')))
        #print(str(BMS_Data.getdata(cell=1, type='mxT')))
        self.line8.setText(str(BMS_Data.getdata(cell=1, type='mnT')))
        #print(str(BMS_Data.getdata(cell=1, type='mnT')))
        self.line9.setText(str(BMS_Data.getdata(cell=1, type='hvb')))
        #print(str(BMS_Data.getdata(cell=1, type='hvb')))
        self.line10.setText(str(BMS_Data.getdata(cell=1, type='te')))
        #print(str(BMS_Data.getdata(cell=1, type='te')))
        #self.line11.setText(str(self.d.getdata(cell=1, type='airLsAux')))
        #self.line12.setText(str(self.d.getdata(cell=1, type='airHsAux')))
        #self.line13.setText(str(self.d.getdata(cell=1, type='hvb')))
        #self.line14.setText(str(self.d.getdata(cell=1, type='sl')))

    def start_Balancing(self):

        self.respond.setMinimumSize(30, 30)

        if BMS_ControlParameter.getConnectionState():
            try:

                if self.sender().text() == 'Start Balancing':
                    self.startBalancing.setText('Stop Balancing')
                    self.com1.balancing(self.bus)
                    print('balancing on')
                    self.respond.setPixmap(self.i.scaled(30, 30))
                    self.t.timeout.connect(lambda: threading.Thread(
                        target=self.response(self.t, self.respond)).start())
                    self.t.start(2000)

                else:
                    self.startBalancing.setText('Start Balancing')
                    self.com1.stop_balancing(self.bus)
                    print('balancing off')
                    self.respond.setPixmap(self.i.scaled(30, 30))
                    self.t.timeout.connect(lambda: threading.Thread(
                        target=self.response(self.t, self.respond)).start())
                    self.t.start(2000)
            except Exception as e:

                self.respond.setPixmap(self.ie.scaled(30, 30))
                logging.error(traceback.format_exc())
        else:
            print("you need to be connected")

    def response(self, timer, label):
        label.clear()
        timer.stop()

    def HV_clicked(self):
        self.respond1.setMinimumSize(30, 30)

        if BMS_ControlParameter.getConnectionState():
            try:
                BMS_Data.setHv(1)
                self.com1.HV_simulate(self.bus)

                self.respond1.setPixmap(self.i_hv.scaled(30, 30))

                #self.t1.timeout.connect(lambda: threading.Thread(target=self.response(self.t1,self.respond1)).start())
                #self.t1.start(2000)

            except Exception as e:
                self.respond1.setPixmap(self.ie.scaled(30, 30))

                logging.error(traceback.format_exc())
        else:
            print("you need to be connected")

    """def no_pcan(self):
        self.warning_label.setText('NO PCAN ADAPTER IS DETECTED, PLEASE PLUG ADAPTER AND RESTART THE PROGRAM')"""

    def controlFan(self, x):

        if self.enable.isChecked(
        ):  #the check box needs to be checked in order to execute any command
            if BMS_ControlParameter.getConnectionState(
            ):  #there needs to be connection in order to execute any command
                try:
                    print(x)

                    if (x >= 0) and (x <= 100):
                        self.com1.sendFanControl(self.bus, x)

                except Exception as e:
                    #self.enable.setChecked(False)
                    logging.error(traceback.format_exc())
            else:
                print("you need to be connected")

    def sendUserFlag(self):
        sender = self.sender()
        if BMS_ControlParameter.getConnectionState() and sender.isChecked():
            self.com1.setUserFlag(self.bus)
            print('set')
        elif BMS_ControlParameter.getConnectionState() and not (
                sender.isChecked()):
            self.com1.resetUserFlag(self.bus)
            print('reset')
        else:
            print('not Connected')


####################################################################################################################