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)
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()
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'])))
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)
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)
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)
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)
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)
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()
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
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)
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()
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