class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.amtLabel = QLabel('Loan Amount')
        self.roiLabel = QLabel('Rate of Interest')
        self.yrsLabel = QLabel('No. of Years')
        self.emiLabel = QLabel('EMI per month')
        self.emiValue = QLCDNumber()
        self.emiValue.setSegmentStyle(QLCDNumber.Flat)
        self.emiValue.setFixedSize(QSize(130, 30))
        self.emiValue.setDigitCount(8)
        self.amtText = QLineEdit('10000')
        self.roiSpin = QSpinBox()
        self.roiSpin.setMinimum(1)
        self.roiSpin.setMaximum(15)
        self.yrsSpin = QSpinBox()
        self.yrsSpin.setMinimum(1)
        self.yrsSpin.setMaximum(20)
        self.roiDial = QDial()
        self.roiDial.setNotchesVisible(True)
        self.roiDial.setMaximum(15)
        self.roiDial.setMinimum(1)
        self.roiDial.setValue(1)
        self.yrsSlide = QSlider(Qt.Horizontal)
        self.yrsSlide.setMaximum(20)
        self.yrsSlide.setMinimum(1)
        self.calculateButton = QPushButton('Calculate EMI')
        self.myGridLayout = QGridLayout()
        self.myGridLayout.addWidget(self.amtLabel, 0, 0)
        self.myGridLayout.addWidget(self.roiLabel, 1, 0)
        self.myGridLayout.addWidget(self.yrsLabel, 2, 0)
        self.myGridLayout.addWidget(self.amtText, 0, 1)
        self.myGridLayout.addWidget(self.roiSpin, 1, 1)
        self.myGridLayout.addWidget(self.yrsSpin, 2, 1)
        self.myGridLayout.addWidget(self.roiDial, 1, 2)
        self.myGridLayout.addWidget(self.yrsSlide, 2, 2)
        self.myGridLayout.addWidget(self.calculateButton, 3, 1)
        self.setLayout(self.myGridLayout)
        self.setWindowTitle("A simple EMI calculator")
        self.roiDial.valueChanged.connect(self.roiSpin.setValue)
        self.connect(self.roiSpin, SIGNAL("valueChanged(int)"), self.roiDial.setValue)
        self.yrsSlide.valueChanged.connect(self.yrsSpin.setValue)
        self.connect(self.yrsSpin, SIGNAL("valueChanged(int)"),self.yrsSlide, SLOT("setValue(int)"))
        self.connect(self.calculateButton, SIGNAL("clicked()"),self.showEMI)

    def showEMI(self):
        loanAmount = float(self.amtText.text())
        rateInterest = float(float(self.roiSpin.value() / 12) / 100)
        noMonths = int(self.yrsSpin.value() * 12)
        emi = (loanAmount * rateInterest) * ((((1 + rateInterest) ** noMonths) / (((1 + rateInterest) ** noMonths) - 1)))
        self.emiValue.display(emi)
        self.myGridLayout.addWidget(self.emiLabel, 4, 0)
        self.myGridLayout.addWidget(self.emiValue, 4, 2)
Beispiel #2
0
class ScoreWidget(QWidget):
    normal_style = """
        background-color: black;
        color: green;
    """
    highlight_style = """
        background-color: green;
        color: white;
    """

    font = QFont("mono", 22)

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.score = QLCDNumber()
        self.score.setMinimumHeight(80)
        self.score.setStyleSheet(self.normal_style)
        self.layout.addWidget(self.score)

        self.player = QLineEdit()
        self.player.setStyleSheet(self.normal_style)
        self.player.setFont(self.font)
        self.player.setAlignment(Qt.AlignCenter)
        self.layout.addWidget(self.player)

    def lock(self):
        self.player.setReadOnly(True)
        self.player.setFocusPolicy(Qt.NoFocus)

    def unlock(self):
        self.score.display(0)
        self.player.setReadOnly(False)
        self.player.setFocusPolicy(Qt.StrongFocus)

    def highlight(self):
        self.player.setStyleSheet(self.highlight_style)
        self.score.setStyleSheet(self.highlight_style)

    def unhighlight(self):
        self.player.setStyleSheet(self.normal_style)
        self.score.setStyleSheet(self.normal_style)

    def adjustScore(self, score_adjustment):
        score = self.score.intValue() + score_adjustment
        self.score.display(score)

    def getScore(self):
        return self.score.intValue()
Beispiel #3
0
class Demo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(300, 300)

        #输入个人信息
        label1 = QLabel("请输入姓名")
        name = QLineEdit()

        #文本标签
        label2 = QLabel("请选择测试项目")
        label2.resize(20, 20)

        #下拉选择框
        cb = QComboBox(self)
        cb.move(100, 50)
        cb.addItem('仰卧起坐')
        cb.addItem('俯卧撑')
        cb.addItem('引体向上')

        #开始 结束测试按钮
        button1 = QPushButton("开始测试")
        button1.clicked.connect(self.start)

        #倒计时功能
        self.a = 60
        self.clock = QLCDNumber()
        self.clock.display(self.a)

        #布局
        layout = QVBoxLayout(self)
        layout.addWidget(label1)
        layout.addWidget(name)
        layout.addWidget(label2)
        layout.addWidget(cb)
        layout.addWidget(button1)
        layout.addWidget(self.clock)
        self.setLayout(layout)

    def start(self):
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.updateTime)
        self.timer.start(1000)

    def updateTime(self):
        if self.a >= 0:
            self.a -= 1
        self.clock.display(self.a)
class TopWidget(QFrame):
    # TODO: Use Qt's embedded resources for images and icons
    _icon_locations = {
        'smile': './assets/smile.jpg',
        'open': './assets/open.jpg',
        'dead': './assets/dead.jpg'
    }

    def __init__(self, bomb_count: int, parent=None):
        super(TopWidget, self).__init__(parent)
        self.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        self.setLineWidth(3)
        self.setMidLineWidth(3)
        self.center = parent

        self.bombCounter = QLCDNumber(len(str(bomb_count)) + 1)
        p = self.bombCounter.palette()
        p.setColor(QPalette.Background, Qt.black)
        p.setColor(p.Light, Qt.darkRed)
        self.bombCounter.setPalette(p)
        self.bombCounter.display(bomb_count)

        self.resetButton = QToolButton()
        self.resetButton.setIcon(QIcon(self._icon_locations['smile']))
        self.resetButton.clicked.connect(self.center.board.reset_board)

        self.timer = CustomTimer(1000)

        upper_layout = QHBoxLayout()
        upper_layout.setMargin(5)
        upper_layout.addWidget(self.bombCounter)
        upper_layout.addWidget(self.resetButton)
        upper_layout.addWidget(self.timer)
        upper_layout.setAlignment(self.bombCounter, Qt.AlignLeft)
        upper_layout.setAlignment(self.resetButton, Qt.AlignHCenter)
        upper_layout.setAlignment(self.timer, Qt.AlignRight)

        self.setLayout(upper_layout)

    def update_counter(self, counter: int):
        self.bombCounter.display(counter)

    def kill_smile(self):
        self.resetButton.setIcon(QIcon(self._icon_locations['dead']))

    def revive_smile(self):
        self.resetButton.setIcon((QIcon(self._icon_locations['smile'])))
Beispiel #5
0
class LCDNumberSlider(QWidget):
    current_value = Signal(int)

    def __init__(self, minval, maxval, startval, numdigits, background, color):
        super().__init__()

        self.lcd = QLCDNumber()
        self.lcd.setDigitCount(numdigits)
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        self.lcd.setStyleSheet(
            f"""QLCDNumber {{ background-color: {background}; color: {color}; }}"""
        )

        self.slider = QSlider(Qt.Vertical)
        self.slider.setMinimum(minval)
        self.slider.setMaximum(maxval)
        self.slider.valueChanged.connect(self.display_slider_value_in_lcd)

        self.slider.setValue(startval)
        self.display_slider_value_in_lcd()

        grid = QGridLayout()
        grid.addWidget(self.lcd, 0, 0, 4, 4)
        grid.addWidget(self.slider, 0, 4, 4, 1)
        self.setLayout(grid)

        self.show()

    def display_slider_value_in_lcd(self):
        self.lcd.display(f'{{:0{self.lcd.digitCount()}}}'.format(
            self.slider.value()))
        self.current_value.emit(self.slider.value())

    def get_current_value(self):
        return self.slider.value()

    def setEnabled(self, enabled):
        self.slider.setEnabled(enabled)
        self.lcd.setSegmentStyle(
            QLCDNumber.Flat) if not enabled else self.lcd.setSegmentStyle(
                QLCDNumber.Filled)
Beispiel #6
0
class OutputWidget(QWidget):
    def __init__(self, line1: str, line2: str, valor: float):
        super().__init__()
        vBox = QVBoxLayout(self)
        lb1 = QLabel(line1)
        lb1.setAlignment(Qt.AlignCenter)
        self.out = QLCDNumber()
        self.out.setDigitCount(7)
        self.out.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.out.setMinimumSize(90, 60)
        self.out.setSegmentStyle(QLCDNumber.SegmentStyle.Flat)
        self.out.display(valor)
        self.out.setStyleSheet(
            "QLCDNumber { background-color: white;  color: red; }")
        vBox.addWidget(lb1)
        if line2 != '':
            lb2 = QLabel(line2)
            lb2.setAlignment(Qt.AlignCenter)
            vBox.addWidget(lb2)
        vBox.addWidget(self.out)
        vBox.setAlignment(Qt.AlignTop | Qt.AlignLeft)
Beispiel #7
0
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        grid = QGridLayout()
        self.setLayout(grid)

        self.setGeometry(300, 300, 400, 300)
        self.setWindowTitle('Grid')

        self.lcd = QLCDNumber()
        grid.addWidget(self.lcd, 0, 0, 3, 0)
        grid.setSpacing(10)

        names = [
            'Cls', 'Bc', '', 'Close', '7', '8', '9', '/', '4', '5', '6', '*',
            '1', '2', '3', '-', '0', '.', '=', '+'
        ]

        positions = [(i, j) for i in range(4, 9) for j in range(4, 8)]

        for position, name in zip(positions, names):
            if name == '':
                continue
            button = QPushButton(name)
            grid.addWidget(button, *position)
            button.clicked.connect(self.aa)

        self.show()

    def aa(self):
        sender = self.sender().text()
        ls = ['/', '*', '-', '=', '+']
        if sender in ls:
            self.lcd.display('A')
        else:
            self.lcd.display(sender)
Beispiel #8
0
class TLoginWindow(QWidget, QtCore.QObject):
    def __init__(self):
        super().__init__()

        self.resize(300,300)
        
        #输入个人信息
        label_name=QLabel("请输入姓名")
        self.edit_name=QLineEdit()
        
        #文本标签
        label_pos=QLabel("请选择测试项目")
        label_pos.resize(20,20)
        
        #下拉选择框
        self.cbox_pos=QComboBox(self)
        self.cbox_pos.move(100,50)
        self.cbox_pos.addItem('仰卧起坐')
        self.cbox_pos.addItem('俯卧撑')
        self.cbox_pos.addItem('引体向上')

        #开始测试按钮
        self.start_button = QPushButton("开始测试")
        # button1.clicked.connect(self.start)

        #倒计时功能
        init = 60
        self.lcd_cntDown=QLCDNumber()
        self.lcd_cntDown.display(init)
        
        #布局
        layout =QVBoxLayout(self)
        layout.addWidget(label_name)
        layout.addWidget(self.edit_name)
        layout.addWidget(label_pos)
        layout.addWidget(self.cbox_pos)
        layout.addWidget(self.start_button)
        layout.addWidget(self.lcd_cntDown)
        self.setLayout(layout)
class Calculator(QWidget):
    # Key Layout
    keys_info = [
        {
            "label": "C",
            "x": 0,
            "y": 1,
            "w": 1,
            "h": 1,
            "name": "Cls",
            "method": "on_clear"
        },
        {
            "label": "√",
            "x": 1,
            "y": 1,
            "w": 1,
            "h": 1,
            "name": "Fnc",
            "method": "on_function"
        },
        {
            "label": "±",
            "x": 2,
            "y": 1,
            "w": 1,
            "h": 1,
            "name": "Fnc",
            "method": "on_function"
        },
        {
            "label": "÷",
            "x": 3,
            "y": 1,
            "w": 1,
            "h": 1,
            "name": "Ope",
            "method": "on_operation"
        },
        {
            "label": "7",
            "x": 0,
            "y": 2,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "8",
            "x": 1,
            "y": 2,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "9",
            "x": 2,
            "y": 2,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "×",
            "x": 3,
            "y": 2,
            "w": 1,
            "h": 1,
            "name": "Ope",
            "method": "on_operation"
        },
        {
            "label": "4",
            "x": 0,
            "y": 3,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "5",
            "x": 1,
            "y": 3,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "6",
            "x": 2,
            "y": 3,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "−",
            "x": 3,
            "y": 3,
            "w": 1,
            "h": 1,
            "name": "Ope",
            "method": "on_operation"
        },
        {
            "label": "1",
            "x": 0,
            "y": 4,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "2",
            "x": 1,
            "y": 4,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "3",
            "x": 2,
            "y": 4,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "+",
            "x": 3,
            "y": 4,
            "w": 1,
            "h": 2,
            "name": "Ope",
            "method": "on_operation"
        },
        {
            "label": "0",
            "x": 0,
            "y": 5,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_number"
        },
        {
            "label": "・",
            "x": 1,
            "y": 5,
            "w": 1,
            "h": 1,
            "name": "Key",
            "method": "on_dot"
        },
        {
            "label": "=",
            "x": 2,
            "y": 5,
            "w": 1,
            "h": 1,
            "name": "Ope",
            "method": "on_equal"
        },
    ]

    # max length
    max_chars = 12

    # operation flag
    flag_dot = False
    flag_operation = False
    flag_error = False

    # register for calculation
    reg = queue.Queue()

    # regular expression
    re1 = re.compile("([\-0-9]+)\.$")
    re2 = re.compile("([\-0-9]+\.)0$")

    def __init__(self):
        super().__init__()
        self.initUI()
        self.setWindowTitle('Calculator')
        self.setWindowFlags(Qt.WindowMinimizeButtonHint
                            | Qt.WindowCloseButtonHint)
        self.show()

    def initUI(self):
        grid = QGridLayout()
        grid.setHorizontalSpacing(2)
        grid.setVerticalSpacing(2)
        # Reference
        # https://stackoverflow.com/questions/16673074/how-can-i-fully-disable-resizing-a-window-including-the-resize-icon-when-the-mou
        grid.setSizeConstraint(QLayout.SetFixedSize)
        self.setLayout(grid)

        # This is register
        self.ent = Register()

        # This is display value of register
        self.lcd = QLCDNumber(self)
        self.lcd.setDigitCount(self.max_chars + 2)
        self.lcd.setSmallDecimalPoint(True)
        self.lcd.display(self.ent.get_text())
        self.lcd.setStyleSheet("QLCDNumber {color:darkgreen;}")
        self.lcd.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        grid.addWidget(self.lcd, 0, 0, 1, 4)
        grid.setRowMinimumHeight(0, 40)

        for key in self.keys_info:
            but = QPushButton(key['label'])
            method_name = key['method']
            method = getattr(self, method_name)
            but.clicked.connect(method)
            but.setStyleSheet(
                "QPushButton {font-size:12pt; padding:5px 30px; color:#666;}")
            but.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            grid.addWidget(but, key['y'], key['x'], key['h'], key['w'])

    # -------------------------------------------------------------------------
    #  get_display_string
    #
    #  argument
    #    value : value to display
    #
    #  return
    #    string to display
    # -------------------------------------------------------------------------
    def get_display_string(self, value):
        if self.flag_error:
            return value

        str_value = str(value)
        self.ent.set_text(str_value)

        m = pow(10.0, self.max_chars)
        value_int = int(value)
        if abs(value_int) > 0:
            value_int_length = int(math.log10(abs(value_int))) + 1
            if value_int_length < self.max_chars:
                if abs(value - value_int) < 1 / m:
                    str_value = str(value_int)
                else:
                    str_value = str(int(value * m) / m)
                    while len(str_value) > self.max_chars:
                        m = m / 10
                        str_value = str(int(value * m) / m)
            else:
                str_value = '{:.3e}'.format(value)
        else:
            if value < 1 / m:
                str_value = '{:.3e}'.format(value)
            else:
                str_value = str(int(value * m) / m)

        result = self.re2.match(str_value)
        if result:
            str_value = result.group(1)
            return str_value

        return str_value

    # -------------------------------------------------------------------------
    #  get_function_result
    #
    #  arguments
    #    text  : function operator
    #    value : value of function parameter
    #
    #  return
    #    value calculated specified function
    # -------------------------------------------------------------------------
    def get_function_result(self, text, value):
        # sign
        if text == "±":
            return value * -1
        # square root
        if text == "√":
            try:
                return math.sqrt(value)
            except Exception as e:
                self.flag_error = True
                #return e
                return "Error"

    # -------------------------------------------------------------------------
    #  get_operator
    #
    #  argument
    #    text : label string of calculator key pad
    #
    #  return
    #    operator string
    # -------------------------------------------------------------------------
    def get_operator(self, text):
        if text == "+":
            return "+"
        if text == "−":
            return "-"
        if text == "×":
            return "*"
        if text == "÷":
            return "/"

    # -------------------------------------------------------------------------
    #  set_display
    #
    #  argument
    #    text : string to display
    # -------------------------------------------------------------------------
    def set_display(self, text):
        self.lcd.display(text)

    # -------------------------------------------------------------------------
    #  zenkaku_to_hankaku
    #
    #  argument
    #    text : zenkaku string
    #
    #  return
    #    hankaku (ascii) string
    # -------------------------------------------------------------------------
    def zenkaku_to_hankaku(self, text):
        # ref: https://qiita.com/YuukiMiyoshi/items/6ce77bf402a29a99f1bf
        return text.translate(
            str.maketrans({chr(0xFF01 + i): chr(0x21 + i)
                           for i in range(94)}))

    # =========================================================================
    #  BINDINGS
    # =========================================================================
    # -------------------------------------------------------------------------
    #  on_clear
    # -------------------------------------------------------------------------
    def on_clear(self):
        # display
        self.ent.init()
        self.set_display(self.ent.get_text())

        # clear flag
        self.flag_dot = False
        self.flag_operation = False
        self.flag_error = False

    # -------------------------------------------------------------------------
    #  on_dot
    # -------------------------------------------------------------------------
    def on_dot(self):
        if self.flag_error:
            return

        # flag
        self.flag_dot = True

    # -------------------------------------------------------------------------
    #  on_equal
    # -------------------------------------------------------------------------
    def on_equal(self):
        if self.flag_error:
            return

        expr = ""
        while not self.reg.empty():
            expr += self.reg.get()

        expr += self.ent.get_text()

        try:
            result = eval(expr)
        except Exception as e:
            self.flag_error = True
            #result = e
            result = "Error"

        disp_new = self.get_display_string(result)

        # display
        self.set_display(disp_new)

        # flag
        self.flag_operation = True

    # -------------------------------------------------------------------------
    #  on_function
    # -------------------------------------------------------------------------
    def on_function(self):
        button = self.sender()
        if self.flag_error:
            return

        # get current value displayed
        value_current = float(self.ent.get_text())

        # get string from key label
        text = button.text()

        value_new = self.get_function_result(text, value_current)
        disp_new = self.get_display_string(value_new)

        # display
        self.set_display(disp_new)

        # flag
        self.flag_operation = True

    # -------------------------------------------------------------------------
    #  on_operation
    # -------------------------------------------------------------------------
    def on_operation(self):
        button = self.sender()
        if self.flag_error:
            return

        # get current string displayed
        disp_current = self.ent.get_text()
        self.reg.put(disp_current)

        # get string from key label
        text = button.text()
        self.reg.put(self.get_operator(text))

        # flag
        self.flag_operation = True
        self.flag_dot = False

    # -------------------------------------------------------------------------
    #  on_number
    # -------------------------------------------------------------------------
    def on_number(self):
        button = self.sender()
        if self.flag_error:
            return

        # get current string displayed
        disp_current = self.ent.get_text()

        # get string from key label
        text = button.text()
        text_ascii = self.zenkaku_to_hankaku(text)

        # update string to display
        if self.flag_operation:
            disp_new = text_ascii + "."
            self.flag_operation = False
        else:
            if disp_current == "0.":
                if self.flag_dot:
                    disp_new = disp_current + text_ascii
                else:
                    disp_new = text_ascii + "."
            else:
                # check charcter length (digit)
                if len(disp_current) > self.max_chars:
                    return

                if self.flag_dot:
                    disp_new = disp_current + text_ascii
                else:
                    result = self.re1.match(disp_current)
                    if result:
                        disp_new = result.group(1) + text_ascii + "."
                    else:
                        disp_new = disp_current + text_ascii

        self.ent.set_text(disp_new)
        self.set_display(disp_new)
Beispiel #10
0
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(878, 528)
        icon = QIcon()
        icon.addFile("./icon.ico")
        Dialog.setWindowIcon(icon)
        self.verticalLayout = QVBoxLayout(Dialog)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.questionLable = QLabel(Dialog)
        self.questionLable.setObjectName(u"questionLable")
        font = QFont()
        font.setFamily(u"\u5fae\u8f6f\u96c5\u9ed1")
        font.setPointSize(12)
        self.questionLable.setFont(font)
        self.questionLable.setWordWrap(True)
        self.questionLable.setMargin(0)
        self.questionLable.setIndent(0)

        self.horizontalLayout.addWidget(self.questionLable)

        self.lcd = QLCDNumber(Dialog)
        self.lcd.setObjectName(u"lcd")
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.lcd.sizePolicy().hasHeightForWidth())
        self.lcd.setSizePolicy(sizePolicy)
        self.lcd.setMinimumSize(QSize(120, 60))
        self.lcd.setSmallDecimalPoint(True)
        self.lcd.setDigitCount(4)
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        self.lcd.setProperty("value", 120.000000000000000)

        self.horizontalLayout.addWidget(self.lcd)

        self.verticalLayout.addLayout(self.horizontalLayout)

        self.line = QFrame(Dialog)
        self.line.setObjectName(u"line")
        self.line.setFrameShape(QFrame.HLine)
        self.line.setFrameShadow(QFrame.Sunken)

        self.verticalLayout.addWidget(self.line)

        self.answerLable = QLabel(Dialog)
        self.answerLable.setObjectName(u"answerLable")
        font1 = QFont()
        font1.setFamily(u"Yu Gothic UI")
        font1.setPointSize(14)
        self.answerLable.setFont(font1)
        self.answerLable.setWordWrap(True)

        self.verticalLayout.addWidget(self.answerLable)

        self.retranslateUi(Dialog)

        QMetaObject.connectSlotsByName(Dialog)

    # setupUi

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(
            QCoreApplication.translate("Dialog", u"Dialog", None))

    # retranslateUi

    def setupUi_(self, question, answer, time):
        self.questionLable.setText(question)
        self.answerLable.setText(answer)
        self.lcd.setDigitCount(3)  # 设置lcd的显示位数
        self.lcd.display(time)
        self.timer1 = QTimer()
        self.timer1.timeout.connect(self.setlcd1)
        self.timer1.start(1000)
        # self.timer2 = QTimer()
        # self.timer2.timeout.connect(self.setlcd2)

    def setlcd1(self):
        self.lcd.display(self.lcd.intValue() - 1)
        if self.lcd.intValue() == 0:
            self.timer1.stop()

            # self.lcd.setSegmentStyle(QLCDNumber.Flat)
            # self.lcd.setStyleSheet("color: red;")

            # self.timer2.start(1000)

    def setlcd2(self):
        self.lcd.display(self.lcd.intValue() + 1)
Beispiel #11
0
class MyWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle(
            'Graphical utility for destroying, zeroing, and deleting files')

        self.label_donate = QLabel(
            'Copyright (c) 2021, Aleksandr Suvorov | Donate: 4048 0250 0089 5923'
        )
        self.label_donate.setAlignment(Qt.AlignCenter)

        self.label_logo = QLabel(f'Smart Cleaner<sup> {VERSION}</sup>')
        self.label_logo.setAlignment(Qt.AlignCenter)
        self.label_logo.setStyleSheet('font-size: 48px;')

        self.label_files = QLabel('Files')
        self.label_files.setStyleSheet("color: rgb(84, 180, 40);")

        self.label_dirs = QLabel('Folders')
        self.label_dirs.setStyleSheet("color: rgb(177, 98, 42);")

        self.label_errors = QLabel('Errors')
        self.label_errors.setStyleSheet("color: rgb(255, 68, 44);")

        self.lcd_files = QLCDNumber()
        self.lcd_files.setSegmentStyle(QLCDNumber.Flat)
        self.lcd_files.setStyleSheet("color: rgb(84, 180, 40);")
        self.lcd_dirs = QLCDNumber()
        self.lcd_dirs.setSegmentStyle(QLCDNumber.Flat)
        self.lcd_dirs.setStyleSheet("color: rgb(177, 98, 42);")
        self.lcd_errors = QLCDNumber()
        self.lcd_errors.setSegmentStyle(QLCDNumber.Flat)
        self.lcd_errors.setMinimumHeight(30)
        self.lcd_errors.setStyleSheet("color: rgb(255, 68, 44);")
        self.lcd_files.setDigitCount(15)
        self.lcd_dirs.setDigitCount(15)
        self.lcd_errors.setDigitCount(15)

        self.h_box1 = QHBoxLayout()
        self.h_box1.addWidget(self.label_dirs)
        self.h_box1.addWidget(self.label_files)
        self.h_box1.addWidget(self.label_errors)

        self.h_box2 = QHBoxLayout()
        self.h_box2.addWidget(self.lcd_dirs)
        self.h_box2.addWidget(self.lcd_files)
        self.h_box2.addWidget(self.lcd_errors)

        self.label_cons = QLabel('Information console:')

        self.text_browser = QTextBrowser()
        self.text_browser.setText(
            f'Smart Cleaner v{VERSION} \nUtility for overwriting, zeroing, and deleting files\n'
            f'https://github.com/mysmarthub')

        self.btn_console_clear = QPushButton('Reset')
        self.btn_donate = QPushButton('Donate | Visa: 4048 0250 0089 5923')
        self.btn_donate.setToolTip(
            'We will be grateful for any financial support.\nThis will help the program '
            'develop and remain free.\nThanks!')
        self.btn_exit = QPushButton('Exit')

        self.h_box3 = QHBoxLayout()
        self.h_box3.addWidget(self.btn_donate)
        self.h_box3.addStretch(1)
        self.h_box3.addWidget(self.btn_console_clear)

        self.chb_del_dirs = QCheckBox('Delete folders')
        self.chb_del_dirs.setChecked(True)

        self.label_shred = QLabel('Rewrite:')

        self.spin_box = QSpinBox()
        self.spin_box.setMinimum(1)
        self.spin_box.setMaximum(1000)
        self.spin_box.setValue(30)

        self.h_box4 = QHBoxLayout()
        self.h_box4.addWidget(self.chb_del_dirs)
        self.h_box4.addWidget(self.label_shred)
        self.h_box4.addWidget(self.spin_box)
        self.h_box4.addStretch(1)

        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.btn_add_folder = QPushButton('+ Folder')
        self.btn_add_files = QPushButton('+ Files')
        self.btn_remove_item = QPushButton('- Remove')
        self.btn_zero_files = QPushButton('Zeroing')
        self.btn_shred_files = QPushButton('Erasing')
        self.btn_del_files = QPushButton('Delete')

        self.h_box5 = QHBoxLayout()
        self.h_box5.addWidget(self.btn_add_folder)
        self.h_box5.addWidget(self.btn_add_files)
        self.h_box5.addWidget(self.btn_remove_item)
        self.h_box5.addStretch(1)
        self.h_box5.addWidget(self.btn_shred_files)
        self.h_box5.addWidget(self.btn_zero_files)
        self.h_box5.addWidget(self.btn_del_files)
        self.h_box5.addWidget(self.btn_exit)

        self.v_box = QVBoxLayout()
        self.v_box.addWidget(self.label_logo)
        self.v_box.addLayout(self.h_box1)
        self.v_box.addLayout(self.h_box2)
        self.v_box.addWidget(self.label_cons)
        self.v_box.addWidget(self.text_browser)
        self.v_box.addLayout(self.h_box3)
        self.v_box.addLayout(self.h_box4)
        self.v_box.addWidget(self.list_widget)
        self.v_box.addLayout(self.h_box5)
        self.v_box.addWidget(self.label_donate)

        self.setLayout(self.v_box)

        self.smart_cleaner = SmartCleaner()

        self.btn_donate.clicked.connect(
            lambda: webbrowser.open('https://yoomoney.ru/to/4100115206129186'))
        self.btn_console_clear.clicked.connect(self.clear_console)
        self.btn_add_folder.clicked.connect(self.add_dir)
        self.btn_add_files.clicked.connect(self.add_files)
        self.btn_remove_item.clicked.connect(self.remove_items)
        self.btn_shred_files.clicked.connect(self.shred_start)
        self.btn_zero_files.clicked.connect(self.zeroing_start)
        self.btn_del_files.clicked.connect(self.delete_start)
        self.btn_exit.clicked.connect(self.close)
        self.smart_cleaner.signal.connect(self.update_information)
        self.smart_cleaner.started.connect(self.at_start)
        self.smart_cleaner.finished.connect(self.at_finish)

    def clear_console(self):
        self.lcd_dirs.display(0)
        self.lcd_files.display(0)
        self.lcd_errors.display(0)
        self.text_browser.setText(
            f'Smart Cleaner v{VERSION} \nUtility for overwriting, zeroing, and deleting files\n'
            f'https://github.com/mysmarthub')

    def add_dir(self) -> None:
        path = QFileDialog.getExistingDirectory(self,
                                                'Select the folder to add: ')
        self._add_path(path)

    def add_files(self) -> None:
        path_tuple = QFileDialog.getOpenFileNames(self,
                                                  'Select files to add: ')
        for path in path_tuple[0]:
            self._add_path(path)

    def add_item(self, item: str) -> None:
        self.list_widget.addItem(item)

    def remove_items(self) -> None:
        for SelectedItem in self.list_widget.selectedItems():
            self.list_widget.takeItem(self.list_widget.row(SelectedItem))
            self.smart_cleaner.path_data.del_path(SelectedItem.text())
            self.text_browser.append(
                f'{SelectedItem.text()}\nThe path was successfully deleted!!!')

    def _add_path(self, path: str) -> None:
        if path:
            if self.smart_cleaner.path_data.add_path(path):
                self.add_item(path)
                self.text_browser.append(
                    f'{path}\nThe path was added successfully!')
            else:
                self.text_browser.append(
                    f'Error when adding or the path was added earlier!!!')

    def shred_start(self):
        self.start(method='shred')

    def zeroing_start(self):
        self.start(method='zero')

    def delete_start(self):
        self.start(method='del')

    def start(self, method='shred'):
        if not self.smart_cleaner.path_data.is_any_data:
            self.show_msg('Warning!', 'There is no data for mashing!!!')
        else:
            reply = QMessageBox.question(
                self, 'Warning!', 'The data will be destroyed, are you sure?',
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                if method == 'zero':
                    self.text_browser.append('Files are reset to zero.')
                elif method == 'shred':
                    self.text_browser.append('File mashing is started.')
                elif method == 'del':
                    self.text_browser.append('File deletion started.')
                self.smart_cleaner.work_method = method
                self.smart_cleaner.shreds = self.spin_box.value()
                self.smart_cleaner.delete_a_folder = self.chb_del_dirs.isChecked(
                )
                self.smart_cleaner.start()

    def update_information(self, s: str) -> None:
        self.text_browser.append(s)
        self.update_lcd()

    def update_lcd(self) -> None:
        self.lcd_dirs.display(str(self.smart_cleaner.cleaner.count_del_dirs))
        self.lcd_files.display(str(self.smart_cleaner.cleaner.count_del_files))
        self.lcd_errors.display(str(self.smart_cleaner.num_errors))

    def at_start(self):
        self.from_disable(True)

    def at_finish(self) -> None:
        if self.smart_cleaner.work_method != 'zero':
            self.list_widget.clear()
        self.update_lcd()
        self.from_disable(False)
        self.finish_msg()

    def finish_msg(self) -> None:
        if self.smart_cleaner.work_method == 'zero':
            msg = ('Reset', 'Reset files: ')
            count = self.smart_cleaner.cleaner.count_zero_files
        elif self.smart_cleaner.work_method == 'shred':
            msg = ('Mashing', 'Passageways: ')
            count = self.smart_cleaner.cleaner.count_del_files
        else:
            msg = ('Delete', 'Deleted files: ')
            count = self.smart_cleaner.cleaner.count_del_files
        self.show_msg(
            'Warning!', f'{msg[0]} completed successfully!!!\n'
            f' {msg[1]} {count}\n '
            f'Deleted folders: {self.smart_cleaner.cleaner.count_del_dirs}\n '
            f'Errors: {self.smart_cleaner.num_errors}')

    def from_disable(self, status: bool) -> None:
        self.btn_zero_files.setDisabled(status)
        self.btn_remove_item.setDisabled(status)
        self.btn_add_folder.setDisabled(status)
        self.btn_shred_files.setDisabled(status)
        self.btn_console_clear.setDisabled(status)
        self.btn_add_files.setDisabled(status)
        self.btn_del_files.setDisabled(status)
        self.chb_del_dirs.setDisabled(status)
        self.spin_box.setDisabled(status)
        self.list_widget.setDisabled(status)

    def show_msg(self,
                 title: str = 'Warning!',
                 msg: str = 'Message...') -> None:
        QMessageBox.about(self, title, msg)

    def closeEvent(self, event) -> None:
        reply = QMessageBox.question(
            self, 'Exit', 'Are you sure you want to terminate the program?',
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.hide()
            self.smart_cleaner.wait(3000)
            event.accept()
        else:
            event.ignore()
Beispiel #12
0
class Form(QDialog):
    def __init__(self, parent=None):
        self.round = 0
        self.lcd = QLCDNumber(5)
        self.lcd2 = QLCDNumber(5)
        self.clock = QLCDNumber(5)
        super(Form, self).__init__(parent)
        self.setWindowTitle("Pomodoro")
        # Create widgets
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(1, 99)
        self.slider.setValue(25)
        self.slider2 = QSlider(Qt.Horizontal)
        self.slider2.setRange(1, 99)
        self.slider2.setValue(5)
        self.count = self.slider.value() * 60
        self.rest = self.slider2.value() * 60
        self.taskbar_count = 0
        self.taskbar2_count = 0
        self.text = QLabel("How long should the work period be?")
        self.text2 = QLabel("How long should the rest period be?")
        self.work = QLabel("WORK")
        self.pause = QLabel("REST")
        self.rounds = QLabel("Number of rounds: " + str(self.round))
        self.work.setAlignment(Qt.AlignHCenter)
        self.work.setFont(QFont("Times", 18, QFont.Bold))
        self.pause.setAlignment(Qt.AlignHCenter)
        self.pause.setFont(QFont("Times", 18, QFont.Bold))
        self.button = QPushButton("Start timer")
        self.button2 = QPushButton("Stop timer")
        self.reset = QPushButton("Reset rounds")
        self.lcd.display("25:00")
        self.lcd2.display("05:00")
        mins = 25
        secs = "00"
        self.clock.display(f"{mins}:{secs}")
        self.slider.valueChanged.connect(self.first_display)
        self.slider2.valueChanged.connect(self.second_display)
        self.slider.valueChanged.connect(self.clock_display)
        self.button2.hide()
        self.work.hide()
        self.pause.hide()
        self.clock.hide()
        # Create layout and add widgets
        layout = QVBoxLayout()
        layout.addWidget(self.text)
        layout.addWidget(self.lcd)
        layout.addWidget(self.slider)
        layout.addWidget(self.text2)
        layout.addWidget(self.lcd2)
        layout.addWidget(self.slider2)
        layout.addWidget(self.button)
        layout.addWidget(self.button2)
        layout.addWidget(self.work)
        layout.addWidget(self.pause)
        layout.addWidget(self.clock)
        layout.addWidget(self.rounds)
        layout.addWidget(self.reset)
        # Set dialog layout
        self.setLayout(layout)
        self.systemtray_icon = QSystemTrayIcon(QIcon("snake.png"))
        self.systemtray_icon.show()
        self.systemtray_icon.activated.connect(self.icon_activated)
        self.menu = QMenu(parent)
        self.exit_action = self.menu.addAction("Exit")
        self.systemtray_icon.setContextMenu(self.menu)
        self.exit_action.triggered.connect(self.slot_exit)
        # Add signals
        self.slider.valueChanged.connect(self.count_func)
        self.slider2.valueChanged.connect(self.count_func)
        self.button.clicked.connect(self.button_update)
        self.button.clicked.connect(self.timer_func)
        self.button.clicked.connect(self.round_count)
        self.button2.clicked.connect(self.stop)
        self.reset.clicked.connect(self.reset_rounds)

    def reset_rounds(self):
        self.round = 0
        self.rounds.setText("Number of rounds: " + str(self.round))

    def round_count(self):
        self.round += 1
        self.rounds.setText("Number of rounds: " + str(self.round))

    def icon_activated(self, reason):
        if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
            self.show()

    def closeEvent(self, event):
        self.hide()
        event.ignore()

    def slot_exit(self):
        QApplication.exit(0)

    def first_display(self):
        minute = str(self.slider.sliderPosition())
        second = ":00"
        leading_zero = "0"
        if self.slider.sliderPosition() >= 10:
            self.lcd.display(minute + second)
        else:
            self.lcd.display(leading_zero + minute + second)

    def second_display(self):
        minute = str(self.slider2.sliderPosition())
        second = ":00"
        leading_zero = "0"
        if self.slider2.sliderPosition() >= 10:
            self.lcd2.display(minute + second)
        else:
            self.lcd2.display(leading_zero + minute + second)

    def clock_display(self):
        minute = str(self.slider.sliderPosition())
        second = ":00"
        leading_zero = "0"
        if self.slider.sliderPosition() >= 10:
            self.clock.display(minute + second)
        else:
            self.clock.display(leading_zero + minute + second)

    def count_func(self):
        self.count = self.slider.sliderPosition() * 60
        self.rest = self.slider2.sliderPosition() * 60

    def countdown(self):
        minute, second = divmod(self.count, 60)
        zero = "0"
        show = self.work.show()
        if second < 10 and minute < 10:
            self.clock.display(zero + str(minute) + ":" + zero + str(second))
        elif second < 10:
            self.clock.display(str(minute) + ":" + zero + str(second))
        elif minute < 10:
            self.clock.display(zero + str(minute) + ":" + str(second))
        else:
            self.clock.display(str(minute) + ":" + str(second))
        self.count -= 1
        if self.count < -1:
            self.work.hide()
            self.taskbar_rest()
            show = self.pause.show()
            minute, second = divmod(self.rest, 60)
            zero = "0"
            if self.rest == self.slider2.value() * 60:
                self.show()
            if second < 10 and minute < 10:
                self.clock.display(zero + str(minute) + ":" + zero +
                                   str(second))
            elif second < 10:
                self.clock.display(str(minute) + ":" + zero + str(second))
            elif minute < 10:
                self.clock.display(zero + str(minute) + ":" + str(second))
            else:
                self.clock.display(str(minute) + ":" + str(second))
            self.rest -= 1
            if self.rest < -1:
                self.clock.display("00:00")
                self.taskbar_work()
                self.timer.stop()
                self.stop()
        show

    def timer_func(self):
        timer = QTimer()
        self.timer = timer
        self.timer.timeout.connect(self.countdown)
        self.timer.start(1000)

    def button_update(self):
        self.button.hide()
        self.text.hide()
        self.lcd.hide()
        self.slider.hide()
        self.text2.hide()
        self.lcd2.hide()
        self.slider2.hide()
        self.reset.hide()
        self.clock.show()
        self.button2.show()
        self.work.show()

    def taskbar_rest(self):
        if self.taskbar_count == 0:
            self.systemtray_icon.showMessage("PAUSE", "Time to rest!",
                                             QSystemTrayIcon.Information,
                                             500000)
            self.taskbar_count = 1

    def taskbar_work(self):
        if self.taskbar2_count == 0:
            self.systemtray_icon.showMessage("WORK", "Break over!",
                                             QSystemTrayIcon.Information,
                                             500000)
            self.taskbar2_count = 1

    def stop(self):
        self.timer.stop()
        self.button2.hide()
        self.work.hide()
        self.pause.hide()
        self.clock.hide()
        self.count = self.slider.value() * 60
        self.rest = self.slider2.value() * 60
        self.clock.display(str(self.slider.value()) + ":00")
        self.button.show()
        self.text.show()
        self.lcd.show()
        self.slider.show()
        self.text2.show()
        self.lcd2.show()
        self.slider2.show()
        self.reset.show()
        self.show()
        self.taskbar_count = 0
        self.taskbar2_count = 0
Beispiel #13
0
class ApplicationControlWidget(QWidget):
    """Widget with control buttons for M1M3 operations. Buttons are disabled/enabled and reasonable defaults sets on DetailedState changes."""

    TEXT_START = "&Start"
    """Constants for button titles. Titles are used to select command send to SAL."""
    TEXT_ENABLE = "&Enable"
    TEXT_DISABLE = "&Disable"
    TEXT_STANDBY = "&Standby"
    TEXT_RAISE = "&Raise M1M3"
    TEXT_ABORT_RAISE = "&Abort M1M3 Raise"
    TEXT_LOWER = "&Lower M1M3"
    TEXT_ENTER_ENGINEERING = "&Enter Engineering"
    TEXT_EXIT_ENGINEERING = "&Exit Engineering"
    TEXT_EXIT_CONTROL = "&Exit Control"

    def __init__(self, m1m3):
        super().__init__()

        self.m1m3 = m1m3
        self.lastEnabled = None

        def _addButton(text, onClick, default=False):
            button = QPushButton(text)
            button.clicked.connect(onClick)
            button.setEnabled(False)
            button.setAutoDefault(default)
            return button

        self.startButton = _addButton(self.TEXT_START, self.start, True)
        self.enableButton = _addButton(self.TEXT_ENABLE, self.enable, True)
        self.raiseButton = _addButton(self.TEXT_RAISE, self.raiseControl, True)
        self.engineeringButton = _addButton(self.TEXT_ENTER_ENGINEERING,
                                            self.engineering)
        self.exitButton = _addButton(self.TEXT_STANDBY, self.exit)

        self.supportedNumber = QLCDNumber(6)
        self.supportedNumber.setAutoFillBackground(True)
        self.minPressure = QLCDNumber(6)
        self.minPressure.setAutoFillBackground(True)
        self.maxPressure = QLCDNumber(6)
        self.maxPressure.setAutoFillBackground(True)

        dataLayout = QFormLayout()
        dataLayout.addRow("Supported", self.supportedNumber)
        dataLayout.addRow("Min pressure", self.minPressure)
        dataLayout.addRow("Max pressure", self.maxPressure)

        commandLayout = QVBoxLayout()
        commandLayout.addWidget(self.startButton)
        commandLayout.addWidget(self.enableButton)
        commandLayout.addWidget(self.raiseButton)
        commandLayout.addWidget(self.engineeringButton)
        commandLayout.addWidget(self.exitButton)
        commandLayout.addLayout(dataLayout)
        commandLayout.addStretch()

        self.supportPercentage = QProgressBar()
        self.supportPercentage.setOrientation(Qt.Vertical)
        self.supportPercentage.setRange(0, 100)
        self.supportPercentage.setTextVisible(True)
        self.supportPercentage.setFormat("%p%")

        layout = QHBoxLayout()
        layout.addLayout(commandLayout)
        layout.addWidget(self.supportPercentage)

        self.setLayout(layout)

        # connect SAL signals
        self.m1m3.detailedState.connect(self.detailedState)
        self.m1m3.forceActuatorState.connect(self.forceActuatorState)
        self.m1m3.hardpointMonitorData.connect(self.hardpointMonitorData)

    def disableAllButtons(self):
        if self.lastEnabled is None:
            self.lastEnabled = [
                self.startButton.isEnabled(),
                self.enableButton.isEnabled(),
                self.raiseButton.isEnabled(),
                self.engineeringButton.isEnabled(),
                self.exitButton.isEnabled(),
            ]
        self.startButton.setEnabled(False)
        self.enableButton.setEnabled(False)
        self.raiseButton.setEnabled(False)
        self.engineeringButton.setEnabled(False)
        self.exitButton.setEnabled(False)

    def restoreEnabled(self):
        if self.lastEnabled is None:
            return
        self.startButton.setEnabled(self.lastEnabled[0])
        self.enableButton.setEnabled(self.lastEnabled[1])
        self.raiseButton.setEnabled(self.lastEnabled[2])
        self.engineeringButton.setEnabled(self.lastEnabled[3])
        self.exitButton.setEnabled(self.lastEnabled[4])
        self.lastEnabled = None

    async def command(self, button):
        self.disableAllButtons()
        try:
            if button.text() == self.TEXT_START:
                await self.m1m3.remote.cmd_start.set_start(
                    settingsToApply="Default", timeout=60)
            elif button.text() == self.TEXT_EXIT_CONTROL:
                await self.m1m3.remote.cmd_exitControl.start()
            elif button.text() == self.TEXT_ENABLE:
                await self.m1m3.remote.cmd_enable.start()
            elif button.text() == self.TEXT_DISABLE:
                await self.m1m3.remote.cmd_disable.start()
            elif button.text() == self.TEXT_RAISE:
                await self.m1m3.remote.cmd_raiseM1M3.set_start(
                    raiseM1M3=True, bypassReferencePosition=False)
            elif button.text() == self.TEXT_ABORT_RAISE:
                await self.m1m3.remote.cmd_abortRaiseM1M3.start()
            elif button.text() == self.TEXT_LOWER:
                await self.m1m3.remote.cmd_lowerM1M3.start()
            elif button.text() == self.TEXT_ENTER_ENGINEERING:
                await self.m1m3.remote.cmd_enterEngineering.start()
            elif button.text() == self.TEXT_EXIT_ENGINEERING:
                await self.m1m3.remote.cmd_exitEngineering.start()
            elif button.text() == self.TEXT_STANDBY:
                await self.m1m3.remote.cmd_standby.start()
        except base.AckError as ackE:
            warning(
                self,
                f"Error executing button {button.text()}",
                f"Error executing button <i>{button.text()}</i>:<br/>{ackE.ackcmd.result}",
            )
        except RuntimeError as rte:
            warning(
                self,
                f"Error executing {button.text()}",
                f"Executing button <i>{button.text()}</i>:<br/>{str(rte)}",
            )
        finally:
            self.restoreEnabled()

    @asyncSlot()
    async def start(self):
        await self.command(self.startButton)

    @asyncSlot()
    async def enable(self):
        await self.command(self.enableButton)

    @asyncSlot()
    async def raiseControl(self):
        await self.command(self.raiseButton)

    @asyncSlot()
    async def engineering(self):
        await self.command(self.engineeringButton)

    @asyncSlot()
    async def exit(self):
        await self.command(self.exitButton)

    def _setTextEnable(self, button, text):
        button.setText(text)
        button.setEnabled(True)

    @Slot(map)
    def detailedState(self, data):
        self.lastEnabled = None
        if data.detailedState == DetailedState.DISABLED:
            self.raiseButton.setEnabled(False)
            self.engineeringButton.setEnabled(False)
            self._setTextEnable(self.enableButton, self.TEXT_ENABLE)
            self._setTextEnable(self.exitButton, self.TEXT_STANDBY)
            self.enableButton.setDefault(True)
        elif data.detailedState == DetailedState.FAULT:
            self._setTextEnable(self.startButton, self.TEXT_STANDBY)
            self.startButton.setDefault(True)
        elif data.detailedState == DetailedState.OFFLINE:
            self.startButton.setEnabled(False)
        elif data.detailedState == DetailedState.STANDBY:
            self.enableButton.setEnabled(False)
            self._setTextEnable(self.startButton, self.TEXT_START)
            self._setTextEnable(self.exitButton, self.TEXT_EXIT_CONTROL)
            self.startButton.setDefault(True)
        elif data.detailedState == DetailedState.PARKED:
            self._setTextEnable(self.enableButton, self.TEXT_DISABLE)
            self._setTextEnable(self.raiseButton, self.TEXT_RAISE)
            self._setTextEnable(self.engineeringButton,
                                self.TEXT_ENTER_ENGINEERING)
            self.exitButton.setEnabled(False)
            self.raiseButton.setDefault(True)
        elif data.detailedState == DetailedState.RAISING:
            self._setTextEnable(self.raiseButton, self.TEXT_ABORT_RAISE)
            self.engineeringButton.setEnabled(False)
            self.raiseButton.setDefault(True)
        elif data.detailedState == DetailedState.ACTIVE:
            self._setTextEnable(self.raiseButton, self.TEXT_LOWER)
            self._setTextEnable(self.engineeringButton,
                                self.TEXT_ENTER_ENGINEERING)
            self.engineeringButton.setEnabled(True)
        elif data.detailedState == DetailedState.LOWERING:
            pass
        elif data.detailedState == DetailedState.PARKEDENGINEERING:
            self.enableButton.setEnabled(False)
            self._setTextEnable(self.raiseButton, self.TEXT_RAISE)
            self._setTextEnable(self.engineeringButton,
                                self.TEXT_EXIT_ENGINEERING)
        elif data.detailedState == DetailedState.RAISINGENGINEERING:
            self._setTextEnable(self.raiseButton, self.TEXT_ABORT_RAISE)
            self.engineeringButton.setEnabled(False)
        elif data.detailedState == DetailedState.ACTIVEENGINEERING:
            self._setTextEnable(self.raiseButton, self.TEXT_LOWER)
            self.engineeringButton.setEnabled(True)
            self._setTextEnable(self.engineeringButton,
                                self.TEXT_EXIT_ENGINEERING)
        elif data.detailedState == DetailedState.LOWERINGENGINEERING:
            pass
        elif data.detailedState == DetailedState.LOWERINGFAULT:
            self._setTextEnable(self.exitButton, self.TEXT_STANDBY)
        elif data.detailedState == DetailedState.PROFILEHARDPOINTCORRECTIONS:
            pass
        else:
            print(f"Unhandled detailed state {data.detailedState}")

    @Slot(map)
    def forceActuatorState(self, data):
        self.supportPercentage.setValue(data.supportPercentage)
        pal = self.supportedNumber.palette()
        if data.supportPercentage == 0:
            col = QColor(255, 0, 0)
        elif data.supportPercentage < 90:
            col = QColor(0, 0, 255)
        elif data.supportPercentage < 100:
            col = QColor(255, 255, 0)
        else:
            col = QColor(0, 255, 0)
        pal.setColor(pal.Background, col)
        self.supportedNumber.display(f"{data.supportPercentage:.02f}")
        self.supportedNumber.setPalette(pal)

    @Slot(map)
    def hardpointMonitorData(self, data):
        min_d = min(data.breakawayPressure)
        max_d = max(data.breakawayPressure)

        def _getColor(v):
            if v < 110 or v > 127:
                return QColor(255, 0, 0)
            elif v < 115 or v > 125:
                return QColor(255, 255, 0)
            return QColor(0, 255, 0)

        min_pal = self.minPressure.palette()
        min_pal.setColor(min_pal.Background, _getColor(min_d))
        self.minPressure.display(f"{min_d:.02f}")
        self.minPressure.setPalette(min_pal)

        max_pal = self.minPressure.palette()
        max_pal.setColor(max_pal.Background, _getColor(max_d))
        self.maxPressure.display(f"{max_d:.02f}")
        self.maxPressure.setPalette(max_pal)
Beispiel #14
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setupUi(self)

        # Setup numbers.
        for n in range(0, 10):
            getattr(self, 'pushButton_n%s' % n).pressed.connect(lambda v=n: self.input_number(v))

        # Setup operations.
        self.pushButton_add.pressed.connect(lambda: self.operation(operator.add))
        self.pushButton_sub.pressed.connect(lambda: self.operation(operator.sub))
        self.pushButton_mul.pressed.connect(lambda: self.operation(operator.mul))
        self.pushButton_div.pressed.connect(lambda: self.operation(operator.truediv))  # operator.div for Python2.7

        self.pushButton_pc.pressed.connect(self.operation_pc)
        self.pushButton_eq.pressed.connect(self.equals)

        # Setup actions
        self.actionReset.triggered.connect(self.reset)
        self.pushButton_ac.pressed.connect(self.reset)

        self.actionExit.triggered.connect(self.close)

        self.pushButton_m.pressed.connect(self.memory_store)
        self.pushButton_mr.pressed.connect(self.memory_recall)

        self.memory = 0
        self.reset()

        self.show()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(484, 433)
        self.centralWidget = QWidget(MainWindow)
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralWidget.sizePolicy().hasHeightForWidth())
        self.centralWidget.setSizePolicy(sizePolicy)
        self.centralWidget.setObjectName("centralWidget")
        self.verticalLayout_2 = QVBoxLayout(self.centralWidget)
        self.verticalLayout_2.setContentsMargins(11, 11, 11, 11)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")
        self.lcdNumber = QLCDNumber(self.centralWidget)
        self.lcdNumber.setDigitCount(10)
        self.lcdNumber.setObjectName("lcdNumber")
        self.verticalLayout.addWidget(self.lcdNumber)
        self.gridLayout = QGridLayout()
        self.gridLayout.setSpacing(6)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton_n4 = QPushButton(self.centralWidget)
        self.pushButton_n4.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n4.setFont(font)
        self.pushButton_n4.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n4.setObjectName("pushButton_n4")
        self.gridLayout.addWidget(self.pushButton_n4, 3, 0, 1, 1)
        self.pushButton_n1 = QPushButton(self.centralWidget)
        self.pushButton_n1.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n1.setFont(font)
        self.pushButton_n1.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n1.setObjectName("pushButton_n1")
        self.gridLayout.addWidget(self.pushButton_n1, 4, 0, 1, 1)
        self.pushButton_n8 = QPushButton(self.centralWidget)
        self.pushButton_n8.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n8.setFont(font)
        self.pushButton_n8.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n8.setObjectName("pushButton_n8")
        self.gridLayout.addWidget(self.pushButton_n8, 2, 1, 1, 1)
        self.pushButton_mul = QPushButton(self.centralWidget)
        self.pushButton_mul.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_mul.setFont(font)
        self.pushButton_mul.setObjectName("pushButton_mul")
        self.gridLayout.addWidget(self.pushButton_mul, 2, 3, 1, 1)
        self.pushButton_n7 = QPushButton(self.centralWidget)
        self.pushButton_n7.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n7.setFont(font)
        self.pushButton_n7.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n7.setObjectName("pushButton_n7")
        self.gridLayout.addWidget(self.pushButton_n7, 2, 0, 1, 1)
        self.pushButton_n6 = QPushButton(self.centralWidget)
        self.pushButton_n6.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n6.setFont(font)
        self.pushButton_n6.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n6.setObjectName("pushButton_n6")
        self.gridLayout.addWidget(self.pushButton_n6, 3, 2, 1, 1)
        self.pushButton_n5 = QPushButton(self.centralWidget)
        self.pushButton_n5.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n5.setFont(font)
        self.pushButton_n5.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n5.setObjectName("pushButton_n5")
        self.gridLayout.addWidget(self.pushButton_n5, 3, 1, 1, 1)
        self.pushButton_n0 = QPushButton(self.centralWidget)
        self.pushButton_n0.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n0.setFont(font)
        self.pushButton_n0.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n0.setObjectName("pushButton_n0")
        self.gridLayout.addWidget(self.pushButton_n0, 5, 0, 1, 1)
        self.pushButton_n2 = QPushButton(self.centralWidget)
        self.pushButton_n2.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n2.setFont(font)
        self.pushButton_n2.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n2.setObjectName("pushButton_n2")
        self.gridLayout.addWidget(self.pushButton_n2, 4, 1, 1, 1)
        self.pushButton_n9 = QPushButton(self.centralWidget)
        self.pushButton_n9.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n9.setFont(font)
        self.pushButton_n9.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n9.setObjectName("pushButton_n9")
        self.gridLayout.addWidget(self.pushButton_n9, 2, 2, 1, 1)
        self.pushButton_n3 = QPushButton(self.centralWidget)
        self.pushButton_n3.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_n3.setFont(font)
        self.pushButton_n3.setStyleSheet("QPushButton {\n"
"color: #1976D2;\n"
"}")
        self.pushButton_n3.setObjectName("pushButton_n3")
        self.gridLayout.addWidget(self.pushButton_n3, 4, 2, 1, 1)
        self.pushButton_div = QPushButton(self.centralWidget)
        self.pushButton_div.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_div.setFont(font)
        self.pushButton_div.setObjectName("pushButton_div")
        self.gridLayout.addWidget(self.pushButton_div, 1, 3, 1, 1)
        self.pushButton_sub = QPushButton(self.centralWidget)
        self.pushButton_sub.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_sub.setFont(font)
        self.pushButton_sub.setObjectName("pushButton_sub")
        self.gridLayout.addWidget(self.pushButton_sub, 3, 3, 1, 1)
        self.pushButton_add = QPushButton(self.centralWidget)
        self.pushButton_add.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_add.setFont(font)
        self.pushButton_add.setObjectName("pushButton_add")
        self.gridLayout.addWidget(self.pushButton_add, 4, 3, 1, 1)
        self.pushButton_ac = QPushButton(self.centralWidget)
        self.pushButton_ac.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_ac.setFont(font)
        self.pushButton_ac.setStyleSheet("QPushButton {\n"
"    color: #f44336;\n"
"}")
        self.pushButton_ac.setObjectName("pushButton_ac")
        self.gridLayout.addWidget(self.pushButton_ac, 1, 0, 1, 1)
        self.pushButton_mr = QPushButton(self.centralWidget)
        self.pushButton_mr.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_mr.setFont(font)
        self.pushButton_mr.setStyleSheet("QPushButton {\n"
"   color: #FFC107;\n"
"}")
        self.pushButton_mr.setObjectName("pushButton_mr")
        self.gridLayout.addWidget(self.pushButton_mr, 1, 2, 1, 1)
        self.pushButton_m = QPushButton(self.centralWidget)
        self.pushButton_m.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_m.setFont(font)
        self.pushButton_m.setStyleSheet("QPushButton {\n"
"   color: #FFC107;\n"
"}")
        self.pushButton_m.setObjectName("pushButton_m")
        self.gridLayout.addWidget(self.pushButton_m, 1, 1, 1, 1)
        self.pushButton_pc = QPushButton(self.centralWidget)
        self.pushButton_pc.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(False)
        font.setWeight(50)
        self.pushButton_pc.setFont(font)
        self.pushButton_pc.setObjectName("pushButton_pc")
        self.gridLayout.addWidget(self.pushButton_pc, 5, 1, 1, 1)
        self.pushButton_eq = QPushButton(self.centralWidget)
        self.pushButton_eq.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(27)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_eq.setFont(font)
        self.pushButton_eq.setStyleSheet("QPushButton {\n"
"color: #4CAF50;\n"
"}")
        self.pushButton_eq.setObjectName("pushButton_eq")
        self.gridLayout.addWidget(self.pushButton_eq, 5, 2, 1, 2)
        self.verticalLayout.addLayout(self.gridLayout)
        self.verticalLayout_2.addLayout(self.verticalLayout)
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QMenuBar(MainWindow)
        self.menuBar.setGeometry(QRect(0, 0, 484, 22))
        self.menuBar.setObjectName("menuBar")
        self.menuFile = QMenu(self.menuBar)
        self.menuFile.setObjectName("menuFile")
        MainWindow.setMenuBar(self.menuBar)
        self.statusBar = QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)
        self.actionExit = QAction(MainWindow)
        self.actionExit.setObjectName("actionExit")
        self.actionReset = QAction(MainWindow)
        self.actionReset.setObjectName("actionReset")
        self.menuFile.addAction(self.actionReset)
        self.menuFile.addAction(self.actionExit)
        self.menuBar.addAction(self.menuFile.menuAction())

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Calculon"))
        self.pushButton_n4.setText(_translate("MainWindow", "4"))
        self.pushButton_n4.setShortcut(_translate("MainWindow", "4"))
        self.pushButton_n1.setText(_translate("MainWindow", "1"))
        self.pushButton_n1.setShortcut(_translate("MainWindow", "1"))
        self.pushButton_n8.setText(_translate("MainWindow", "8"))
        self.pushButton_n8.setShortcut(_translate("MainWindow", "8"))
        self.pushButton_mul.setText(_translate("MainWindow", "x"))
        self.pushButton_mul.setShortcut(_translate("MainWindow", "*"))
        self.pushButton_n7.setText(_translate("MainWindow", "7"))
        self.pushButton_n7.setShortcut(_translate("MainWindow", "7"))
        self.pushButton_n6.setText(_translate("MainWindow", "6"))
        self.pushButton_n6.setShortcut(_translate("MainWindow", "6"))
        self.pushButton_n5.setText(_translate("MainWindow", "5"))
        self.pushButton_n5.setShortcut(_translate("MainWindow", "5"))
        self.pushButton_n0.setText(_translate("MainWindow", "0"))
        self.pushButton_n0.setShortcut(_translate("MainWindow", "0"))
        self.pushButton_n2.setText(_translate("MainWindow", "2"))
        self.pushButton_n2.setShortcut(_translate("MainWindow", "2"))
        self.pushButton_n9.setText(_translate("MainWindow", "9"))
        self.pushButton_n9.setShortcut(_translate("MainWindow", "9"))
        self.pushButton_n3.setText(_translate("MainWindow", "3"))
        self.pushButton_n3.setShortcut(_translate("MainWindow", "3"))
        self.pushButton_div.setText(_translate("MainWindow", "÷"))
        self.pushButton_div.setShortcut(_translate("MainWindow", "/"))
        self.pushButton_sub.setText(_translate("MainWindow", "-"))
        self.pushButton_sub.setShortcut(_translate("MainWindow", "-"))
        self.pushButton_add.setText(_translate("MainWindow", "+"))
        self.pushButton_add.setShortcut(_translate("MainWindow", "+"))
        self.pushButton_ac.setText(_translate("MainWindow", "AC"))
        self.pushButton_ac.setShortcut(_translate("MainWindow", "Esc"))
        self.pushButton_mr.setText(_translate("MainWindow", "MR"))
        self.pushButton_mr.setShortcut(_translate("MainWindow", "R"))
        self.pushButton_m.setText(_translate("MainWindow", "M"))
        self.pushButton_m.setShortcut(_translate("MainWindow", "M"))
        self.pushButton_pc.setText(_translate("MainWindow", "%"))
        self.pushButton_pc.setShortcut(_translate("MainWindow", "%"))
        self.pushButton_eq.setText(_translate("MainWindow", "="))
        self.pushButton_eq.setShortcut(_translate("MainWindow", "Return"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.actionExit.setText(_translate("MainWindow", "Exit"))
        self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q"))
        self.actionReset.setText(_translate("MainWindow", "Reset"))
        self.actionReset.setShortcut(_translate("MainWindow", "Ctrl+R"))


    def display(self):
        self.lcdNumber.display(self.stack[-1])

    def reset(self):
        self.state = READY
        self.stack = [0]
        self.last_operation = None
        self.current_op = None
        self.display()

    def memory_store(self):
        self.memory = self.lcdNumber.value()

    def memory_recall(self):
        self.state = INPUT
        self.stack[-1] = self.memory
        self.display()

    def input_number(self, v):
        if self.state == READY:
            self.state = INPUT
            self.stack[-1] = v
        else:
            self.stack[-1] = self.stack[-1] * 10 + v

        self.display()

    def operation(self, op):
        if self.current_op:  # Complete the current operation
            self.equals()

        self.stack.append(0)
        self.state = INPUT
        self.current_op = op

    def operation_pc(self):
        self.state = INPUT
        self.stack[-1] *= 0.01
        self.display()

    def equals(self):
        # Support to allow '=' to repeat previous operation
        # if no further input has been added.
        if self.state == READY and self.last_operation:
            s, self.current_op = self.last_operation
            self.stack.append(s)

        if self.current_op:
            self.last_operation = self.stack[-1], self.current_op

            try:
                self.stack = [self.current_op(*self.stack)]
            except Exception:
                self.lcdNumber.display('Err')
                self.stack = [0]
            else:
                self.current_op = None
                self.state = READY
                self.display()
Beispiel #15
0
class MineSweeperWindow(QMainWindow):
    def __init__(self, mode):
        super().__init__()
        self.ms = mode
        self.init_ui()
        self.set_menu()

    def init_ui(self):
        """初始化游戏界面"""
        # 1.确定游戏界面的标题,大小和背景颜色
        self.setObjectName('MainWindow')
        self.setWindowTitle('扫雷')
        self.setWindowIcon(QIcon(':/minesweeper.ico'))
        self.setFixedSize(50 * self.ms.length + 100, 50 * self.ms.width + 180)
        self.setStyleSheet('#MainWindow{background-color: #f6edd2}')
        self.remain_boom = QLCDNumber(2, self)
        self.remain_boom.move(50, 50)
        self.remain_boom.setFixedSize(60, 50)
        self.remain_boom.setStyleSheet(
            "border: 2px solid blue; color: red; background: black;")
        self.remain_boom.display(
            '{:>02d}'.format(self.ms.b_num if self.ms.b_num >= 0 else 0))
        self.timer = QBasicTimer()
        self.second = 0
        self.time = QLCDNumber(3, self)
        self.time.move(50 * self.ms.length - 40, 50)
        self.time.setFixedSize(90, 50)
        self.time.setStyleSheet(
            "border: 2px solid blue; color: red; background: black;")
        self.time.display('{:>03d}'.format(self.second))
        self.btn = QPushButton(self)
        self.btn.move(25 * self.ms.length + 20, 50)
        self.btn.setFixedSize(50, 50)
        self.btn.setIcon(QIcon(':/普通.png'))
        self.btn.setIconSize(QSize(45, 45))
        self.btn.setStyleSheet('QPushButton{border:None}')
        self.btn.clicked.connect(self.restart)
        self.over_signal = 0
        self.rank = sqlite3.connect('rank.db')
        self.c = self.rank.cursor()

    def set_menu(self):
        bar = self.menuBar()
        game = bar.addMenu('游戏(&G)')
        more_info = bar.addMenu('更多(&M)')

        new_game = QAction('新游戏(&N)', self)
        new_game.setShortcut('Ctrl+N')
        new_game.triggered.connect(self.start)
        game.addAction(new_game)
        restart = QAction('重玩(&R)', self)
        restart.setShortcut('Ctrl+R')
        restart.triggered.connect(self.restart)
        game.addAction(restart)
        game.addSeparator()
        self.modes = QActionGroup(self)
        self.easy = QAction('简单(E)', self)
        self.easy.setCheckable(True)
        game.addAction(self.modes.addAction(self.easy))
        self.medium = QAction('中等(M)', self)
        self.medium.setCheckable(True)
        game.addAction(self.modes.addAction(self.medium))
        self.hard = QAction('困难(H)', self)
        self.hard.setCheckable(True)
        game.addAction(self.modes.addAction(self.hard))
        self.modes.triggered.connect(
            lambda: self.set_mode(self.modes.checkedAction()))
        if isinstance(self.ms, EasyMode):
            self.easy.setChecked(True)
        elif isinstance(self.ms, MediumMode):
            self.medium.setChecked(True)
        elif isinstance(self.ms, HardMode):
            self.hard.setChecked(True)

        rank = QAction('排行耪(&R)', self)
        rank.triggered.connect(self.show_rank)
        more_info.addAction(rank)

    def paintEvent(self, e):
        """绘制游戏内容"""
        qp = QPainter()

        def draw_map():
            """绘制版面"""
            # background = QPixmap(':/背景2.png')
            # qp.drawPixmap(self.rect(), background)
            # qp.setBrush(QColor('#e8ff9d'))
            # qp.drawRect(50, 130, 50 * self.ms.length, 50 * self.ms.width)
            for x in range(0, self.ms.length, 2):
                for y in range(0, self.ms.width, 2):
                    qp.setBrush(QColor('#007a15'))
                    qp.drawRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50)
                for y in range(1, self.ms.width, 2):
                    qp.setBrush(QColor('#00701c'))
                    qp.drawRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50)
            for x in range(1, self.ms.length, 2):
                for y in range(0, self.ms.width, 2):
                    qp.setBrush(QColor('#00701c'))
                    qp.drawRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50)
                for y in range(1, self.ms.width, 2):
                    qp.setBrush(QColor('#007a15'))
                    qp.drawRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50)
            # qp.setPen(QPen(QColor(111, 108, 108), 2, Qt.SolidLine))
            # for x in range(self.ms.length + 1):
            #     qp.drawLine(50 * (x + 1), 130, 50 * (x + 1), 50 * self.ms.width + 130)
            # for y in range(self.ms.width + 1):
            #     qp.drawLine(50, 50 * (y + 1) + 80, 50 * self.ms.length + 50, 50 * (y + 1) + 80)

        def draw_blanks():
            qp.setBrush(QColor('#f4f4f4'))
            for x in range(self.ms.length):
                for y in range(self.ms.width):
                    if isinstance(self.ms.g_map[y][x], str):
                        if self.ms.g_map[y][x] == '0$' or self.ms.g_map[y][
                                x] == '1$':
                            # qp.setPen(QPen(QColor(219, 58, 58), 1, Qt.SolidLine))
                            # qp.setFont(QFont('Kai', 15))
                            flag = QPixmap(':/雷旗.png').scaled(50, 50)
                            qp.drawPixmap(
                                QRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50),
                                flag)
                            # qp.drawText(50 * (x + 1) + 18, 50 * (y + 1) + 115, '$')
                            continue
                        qp.setPen(QPen(QColor('black'), 1, Qt.SolidLine))
                        qp.setFont(QFont('Kai', 15))
                        qp.drawRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50)
                        if self.ms.g_map[y][x] == '0':
                            continue
                        if self.ms.g_map[y][x] == '*':
                            flag = QPixmap(':/土豆雷.png').scaled(50, 50)
                            qp.drawPixmap(
                                QRect(50 * (x + 1), 50 * (y + 1) + 80, 50, 50),
                                flag)
                            continue
                        qp.setPen(QPen(QColor('black'), 5, Qt.SolidLine))
                        qp.drawText(50 * (x + 1) + 18, 50 * (y + 1) + 115,
                                    '{}'.format(self.ms.g_map[y][x]))

        qp.begin(self)
        draw_map()
        draw_blanks()
        qp.end()

    def mousePressEvent(self, e):
        """根据鼠标的动作,确定落子位置"""
        if self.over_signal == 1:
            return
        if e.button() in (Qt.LeftButton, Qt.RightButton):
            mouse_x = e.windowPos().x()
            mouse_y = e.windowPos().y()
            if 50 <= mouse_x <= 50 * self.ms.length + 50 and 130 <= mouse_y <= 50 * self.ms.width + 130:
                if self.ms.step == 0:
                    self.timer.start(1000, self)
                    self.tic = time_ns()
                game_x = int(mouse_x // 50) - 1
                game_y = int((mouse_y - 80) // 50) - 1
            else:
                return
            if e.buttons() == Qt.LeftButton | Qt.RightButton:
                self.ms.click_around(game_x, game_y)
            elif e.buttons() == Qt.LeftButton:
                self.ms.click(game_x, game_y)
            else:
                self.ms.mark_mine(game_x, game_y)
        if self.ms.boom:
            self.timer.stop()
            self.btn.setIcon(QIcon(':/哭脸.png'))
            self.btn.setIconSize(QSize(45, 45))
            self.repaint(0, 0, 50 * self.ms.length + 100,
                         50 * self.ms.width + 180)
            self.over_signal = 1
            return
        elif self.ms.game_judge():
            self.timer.stop()
            self.toc = time_ns()
            self.btn.setIconSize(QSize(45, 45))
            self.btn.setIcon(QIcon(':/笑脸.png'))
            self.repaint(0, 0, 50 * self.ms.length + 100,
                         50 * self.ms.width + 180)
            self.check_rank()
            self.over_signal = 1
            return
        self.repaint(0, 0, 50 * self.ms.length + 100, 50 * self.ms.width + 180)
        self.remain_boom.display(
            '{:>02d}'.format(self.ms.b_num if self.ms.b_num >= 0 else 0))

    def timerEvent(self, e) -> None:
        self.second += 1
        self.time.display('{:>03d}'.format(self.second))

    def set_mode(self, action: QAction):
        if action == self.easy:
            self.close()
            self.msw = MineSweeperWindow(EasyMode())
            self.msw.show()
        elif action == self.medium:
            self.close()
            self.msw = MineSweeperWindow(MediumMode())
            self.msw.show()
        elif action == self.hard:
            self.close()
            self.msw = MineSweeperWindow(HardMode())
            self.msw.show()

    def show_rank(self):
        self.sk = ShowRank()
        self.sk.show()

    def start(self):
        self.close()
        self.a = Start()
        self.a.show()

    def restart(self):
        self.ms.refresh()
        self.repaint()
        self.btn.setIcon(QIcon(':/普通.png'))
        self.remain_boom.display(
            '{:>02d}'.format(self.ms.b_num if self.ms.b_num >= 0 else 0))
        self.second = 0
        self.timer.stop()
        self.time.display('{:>03d}'.format(self.second))
        self.over_signal = 0

    def check_rank(self):
        a_num = (self.toc - self.tic) / 10**9
        out = subprocess.check_output("whoami").decode("gbk")
        name = re.search(r"\\(.+)\r\n", out)
        a_user = name.group(1)
        for i in range(5, 0, -1):
            if isinstance(self.ms, EasyMode):
                mode = "Easy"
            elif isinstance(self.ms, MediumMode):
                mode = "Medium"
            elif isinstance(self.ms, HardMode):
                mode = "Hard"
            else:
                return
            self.c.execute("SELECT * FROM {} WHERE id=?;".format(mode), (i, ))
            feedback = self.c.fetchone()
            if i == 5:
                if (not feedback[2]) or (feedback[2] > a_num):
                    a_user, _ = QInputDialog.getText(self,
                                                     "用户名",
                                                     "请输入用户名:",
                                                     QLineEdit.Normal,
                                                     text=a_user)
                    self.c.execute(
                        "UPDATE {} SET user=?, time=? WHERE id=?;".format(
                            mode), (a_user, a_num, i))
                    self.rank.commit()
                    continue
                else:
                    return
            else:
                if (not feedback[2]) or (feedback[2] > a_num):
                    self.c.execute(
                        "UPDATE {0} "
                        "SET user = (SELECT user FROM {0} WHERE id=?), "
                        "time = (SELECT time FROM {0} WHERE id=?)"
                        "WHERE id=? ;".format(mode), (i, i, i + 1))
                    self.c.execute(
                        "UPDATE {} SET user=?, time=? WHERE id=? ;".format(
                            mode), (a_user, a_num, i))
                    self.rank.commit()
                else:
                    return

    def closeEvent(self, e):
        self.rank.commit()
        self.rank.close()
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.speed_logs_databse = []

        # Based on this value engine will run or wil stop running.
        self.engine_run_condition = False

        # Braking functionality get activated based on this variable.
        self.brake_run_condition = False

        # GEAR INDICATOR
        self.gear_indicator = QLabel('CURRENT GEAR INDICATOR')

        # SLIDER
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMaximum(100)
        self.slider.setMinimum(0)

        # LCD NUMBER FOR KMPH
        self.lcd_speed = QLCDNumber(self)
        self.lcd_speed.setStyleSheet("width:300")
        self.lcd_speed.rect().center()

        # LCD INDICATOR FOR CURRENT GEAR
        self.lcd_gear = QLCDNumber(self)

        # START ENGINE BUTTON
        self.start_engine = QPushButton('Start Engine')
        self.start_engine.clicked.connect(self.engine_thread)

        # TURN OFF ENGINE BUTTON
        self.turn_off_engine = QPushButton('Turn Off Engine')
        self.turn_off_engine.clicked.connect(self.turn_off_engine_thread)

        # PRESS BRAKE
        self.brake_pedal = QPushButton('Use Brakes To Slow Down')
        self.brake_pedal.clicked.connect(self.brakes_thread)

        # MAIN APP LAYOUT
        self.appLayout = QVBoxLayout(self)

        # ROW2
        self.row2 = QHBoxLayout(self)
        self.row2.addWidget(self.lcd_speed)
        self.row2.addWidget(self.lcd_gear)

        # ROW3
        self.row3 = QHBoxLayout(self)
        self.row3.addWidget(self.start_engine)
        self.row3.addWidget(self.turn_off_engine)

        # ROW4
        self.row4 = QVBoxLayout(self)
        self.row4.addWidget(self.slider)

        # ROW5
        self.row5 = QVBoxLayout(self)
        self.row5.addWidget(self.gear_indicator)

        # ROW6
        self.row6 = QVBoxLayout(self)
        self.row6.addWidget(self.brake_pedal)

        # APPENDING ROWS TO MAIN APP LAYOUT
        self.appLayout.addLayout(self.row2)
        self.appLayout.addLayout(self.row3)
        self.appLayout.addLayout(self.row4)
        self.appLayout.addLayout(self.row5)
        self.appLayout.addLayout(self.row6)

        # Main Window METADATA
        self.setWindowTitle("Car Dashboard")
        self.setGeometry(300, 300, 600, 800)
        self.setMinimumHeight(600)
        self.setMinimumWidth(800)
        self.setMaximumHeight(600)
        self.setMaximumWidth(800)

        # SETTING MAIN LAYOUT FOR APP
        self.setLayout(self.appLayout)

    # Engine thread which will be responsible for updating GUI values based on engine functionality.
    def engine_thread(self):
        thread = threading.Thread(target=self.engine_logic)
        thread.start()

    # MAIN PHYSICS AND ENGINE LOGIC
    def engine_logic(self):
        self.engine_run_condition = True
        start_time = time.time()
        while self.engine_run_condition:
            time.sleep(0.001)
            gas_pedal = self.slider.value()
            if gas_pedal == 0:
                start_time = time.time()
            self.gear_logic(start_time)

    # Shifting gears based on velocity treshold limit.
    def gear_logic(self, start_time):
        shifting_gears = [{
            "gear": "1",
            "next_gear": "2",
            "prev_gear": "Car has stopped."
        }, {
            "gear": "2",
            "next_gear": "3",
            "prev_gear": "1"
        }, {
            "gear": "3",
            "next_gear": "4",
            "prev_gear": "2"
        }, {
            "gear": "4",
            "next_gear": "5",
            "prev_gear": "4"
        }, {
            "gear": "5",
            "next_gear": "6",
            "prev_gear": "4"
        }, {
            "gear": "6",
            "next_gear": "Gear limit",
            "prev_gear": "5"
        }]

        # Logging al velocity changes while car is moving.
        data_logs = SinglyLinkedList()

        # Max acceleration rate based on BMW X6, 7 m/s^2.
        max_acceleration_rate = 7

        # Throttle percentage, it simulates how hard the gas pedal has being pressed.
        throttle_percentage = self.slider.value()

        # Based on percetage which represents how hard the pedal has being pressed
        current_acceleration = (throttle_percentage /
                                100) * max_acceleration_rate
        # For acceleration we must use start time and end time.
        end_time = time.time()
        final_time = end_time - start_time
        # average speed is: a * t
        current_speed = current_acceleration * final_time
        # current speed is average speed + speed at the moment with that acceleration.
        real_speed = current_speed + current_acceleration * final_time

        self.global_real_speed = real_speed

        # MAX SPEED LIMIT
        if real_speed > 320:
            real_speed = 320

        # AUTO-SWITCHING GEAR SYSTEM
        #!IF THE CURRENT SPEED IS 0, TELL THE DRIVER THAT CAR IS NOT MOVING.
        if real_speed == 0:
            self.gear_indicator.setText('Current gear is: Car is not moving.')
            data_logs.append({"gear": 0, "speeed": real_speed})
        #!IF THE CURRENT SPEED IS IN RANGE(1, 45), SHOW ACTIVE GEAR(1).
        elif 0 < real_speed <= 45:
            self.gear_indicator.setText('Current gear is: {}'.format(
                shifting_gears[0]['gear']))
            self.lcd_gear.display(shifting_gears[0]['gear'])
            data_logs.append({"gear": 1, "speeed": real_speed})
        #!IF THE CURRENT SPEED IS IN RANGE(46, 75), SHOW ACTIVE GEAR(2).
        elif 45 < real_speed <= 75:
            self.gear_indicator.setText('Current gear is: {}'.format(
                shifting_gears[1]['gear']))
            self.lcd_gear.display(shifting_gears[1]['gear'])
            data_logs.append({"gear": 2, "speeed": real_speed})
        #!IF THE CURRENT SPEED IS IN RANGE(76, 110), SHOW ACTIVE GEAR(3).
        elif 75 < real_speed <= 110:
            self.gear_indicator.setText('Current gear is: {}'.format(
                shifting_gears[2]['gear']))
            self.lcd_gear.display(shifting_gears[2]['gear'])
            data_logs.append({"gear": 3, "speeed": real_speed})
        #!IF THE CURRENT SPEED IS IN RANGE(111, 150), SHOW ACTIVE GEAR(4).
        elif 110 < real_speed <= 150:
            self.gear_indicator.setText('Current gear is: {}'.format(
                shifting_gears[3]['gear']))
            self.lcd_gear.display(shifting_gears[3]['gear'])
            data_logs.append({"gear": 4, "speeed": real_speed})
        #!IF THE CURRENT SPEED IS IN RANGE(151, 260), SHOW ACTIVE GEAR(5).
        elif 150 < real_speed <= 260:
            self.gear_indicator.setText('Current gear is: {}'.format(
                shifting_gears[4]['gear']))
            self.lcd_gear.display(shifting_gears[4]['gear'])
            data_logs.append({"gear": 5, "speeed": real_speed})
        #!IF THE CURRENT SPEED IS IN RANGE(261, 320), SHOW ACTIVE GEAR(6).
        elif 260 < real_speed <= 320:
            self.gear_indicator.setText('Current gear is: {}'.format(
                shifting_gears[5]['gear']))
            self.lcd_gear.display(shifting_gears[5]['gear'])
            data_logs.append({"gear": 6, "speeed": real_speed})
        print('Current speed is: {}'.format(real_speed))

        # Update kmph number in GUI
        self.lcd_speed.display(int(real_speed))

        # Handle log data
        for data_log in data_logs:
            self.speed_logs_databse.append(data_log)

    # Brake thread is responsible for braking when Brake action is called.
    def brakes_thread(self):
        brake_thread = threading.Thread(target=self.use_brakes)
        brake_thread.start()

    def use_brakes(self):
        self.brake_run_condition = True
        while self.brake_run_condition:
            print("Brake pedal is being pressed.")
            current_slider_value = self.slider.value()
            for i in range(current_slider_value, -1, -1):
                # based on this formula:
                """Conditions: Good tyres and good brakes.
                    Formula: d = s2 / (250 * f)

                    d = braking distance in metres (to be calculated).
                    s = speed in km/h.
                    250 = fixed figure which is always used.
                    f = coefficient of friction, approx. 0.8 on dry asphalt and 0.1 on ice.

                    Example of calculation with a speed of 50 km/h on dry asphalt:

                    50^2 / (250 * 0.8) = 12.5 metres braking distance
                """
                # breaking time at average speed of 100 kmph
                time.sleep(0.025)
                self.slider.setValue(i)
            self.turn_off_brake_thread()

    # When engines gets turned off, end the engine - thread process.

    def turn_off_engine_thread(self):
        self.engine_run_condition = False
        with open('./speed_system_logs/datalogs.txt', 'w') as f:
            json.dump(self.speed_logs_databse, f)

    # When current velocity reaches 0, end the break - thread process.
    def turn_off_brake_thread(self):
        self.brake_run_condition = False