class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setupTrayicon() self.setupVariables() self.setupUi() self.setupConnections() self.show() def setupVariables(self): settings = QSettings() self.workEndTime = QTime( int(settings.value(workHoursKey, 0)), int(settings.value(workMinutesKey, 25)), int(settings.value(workSecondsKey, 0)), ) self.restEndTime = QTime( int(settings.value(restHoursKey, 0)), int(settings.value(restMinutesKey, 5)), int(settings.value(restSecondsKey, 0)), ) self.timeFormat = "hh:mm:ss" self.time = QTime(0, 0, 0, 0) self.workTime = QTime(0, 0, 0, 0) self.restTime = QTime(0, 0, 0, 0) self.totalTime = QTime(0, 0, 0, 0) self.currentMode = Mode.work self.maxRepetitions = -1 self.currentRepetitions = 0 def setupConnections(self): """ Create button connections """ self.startButton.clicked.connect(self.startTimer) self.startButton.clicked.connect( lambda: self.startButton.setDisabled(True)) self.startButton.clicked.connect( lambda: self.pauseButton.setDisabled(False)) self.startButton.clicked.connect( lambda: self.resetButton.setDisabled(False)) self.pauseButton.clicked.connect(self.pauseTimer) self.pauseButton.clicked.connect( lambda: self.startButton.setDisabled(False)) self.pauseButton.clicked.connect( lambda: self.pauseButton.setDisabled(True)) self.pauseButton.clicked.connect( lambda: self.resetButton.setDisabled(False)) self.pauseButton.clicked.connect( lambda: self.startButton.setText("continue")) self.resetButton.clicked.connect(self.resetTimer) self.resetButton.clicked.connect( lambda: self.startButton.setDisabled(False)) self.resetButton.clicked.connect( lambda: self.pauseButton.setDisabled(True)) self.resetButton.clicked.connect( lambda: self.resetButton.setDisabled(True)) self.resetButton.clicked.connect( lambda: self.startButton.setText("start")) self.acceptTaskButton.pressed.connect(self.insertTask) self.deleteTaskButton.pressed.connect(self.deleteTask) """ Create spinbox connections """ self.workHoursSpinBox.valueChanged.connect(self.updateWorkEndTime) self.workMinutesSpinBox.valueChanged.connect(self.updateWorkEndTime) self.workSecondsSpinBox.valueChanged.connect(self.updateWorkEndTime) self.restHoursSpinBox.valueChanged.connect(self.updateRestEndTime) self.restMinutesSpinBox.valueChanged.connect(self.updateRestEndTime) self.restSecondsSpinBox.valueChanged.connect(self.updateRestEndTime) self.repetitionsSpinBox.valueChanged.connect(self.updateMaxRepetitions) """ Create combobox connections """ self.modeComboBox.currentTextChanged.connect(self.updateCurrentMode) """ Create tablewidget connections """ self.tasksTableWidget.cellDoubleClicked.connect( self.markTaskAsFinished) def setupUi(self): self.size_policy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) """ Create tabwidget """ self.tabWidget = QTabWidget() """ Create tab widgets """ timerWidget = self.setupTimerTab() tasksWidget = self.setupTasksTab() statisticsWidget = self.setupStatisticsTab() """ add tab widgets to tabwidget""" self.timerTab = self.tabWidget.addTab(timerWidget, makeIcon("timer"), "Timer") self.tasksTab = self.tabWidget.addTab(tasksWidget, makeIcon("tasks"), "Tasks") self.statisticsTab = self.tabWidget.addTab(statisticsWidget, makeIcon("statistics"), "Statistics") """ Set mainwindows central widget """ self.setCentralWidget(self.tabWidget) def setupTimerTab(self): settings = QSettings() self.timerContainer = QWidget(self) self.timerContainerLayout = QVBoxLayout(self.timerContainer) self.timerContainer.setLayout(self.timerContainerLayout) """ Create work groupbox""" self.workGroupBox = QGroupBox("Work") self.workGroupBoxLayout = QHBoxLayout(self.workGroupBox) self.workGroupBox.setLayout(self.workGroupBoxLayout) self.workHoursSpinBox = QSpinBox( minimum=0, maximum=24, value=int(settings.value(workHoursKey, 0)), suffix="h", sizePolicy=self.size_policy, ) self.workMinutesSpinBox = QSpinBox( minimum=0, maximum=60, value=int(settings.value(workMinutesKey, 25)), suffix="m", sizePolicy=self.size_policy, ) self.workSecondsSpinBox = QSpinBox( minimum=0, maximum=60, value=int(settings.value(workSecondsKey, 0)), suffix="s", sizePolicy=self.size_policy, ) """ Create rest groupbox""" self.restGroupBox = QGroupBox("Rest") self.restGroupBoxLayout = QHBoxLayout(self.restGroupBox) self.restGroupBox.setLayout(self.restGroupBoxLayout) self.restHoursSpinBox = QSpinBox( minimum=0, maximum=24, value=int(settings.value(restHoursKey, 0)), suffix="h", sizePolicy=self.size_policy, ) self.restMinutesSpinBox = QSpinBox( minimum=0, maximum=60, value=int(settings.value(restMinutesKey, 5)), suffix="m", sizePolicy=self.size_policy, ) self.restSecondsSpinBox = QSpinBox( minimum=0, maximum=60, value=int(settings.value(restSecondsKey, 0)), suffix="s", sizePolicy=self.size_policy, ) self.restGroupBoxLayout.addWidget(self.restHoursSpinBox) self.restGroupBoxLayout.addWidget(self.restMinutesSpinBox) self.restGroupBoxLayout.addWidget(self.restSecondsSpinBox) """ Create other groupbox""" self.otherGroupBox = QGroupBox("Other") self.otherGroupBoxLayout = QHBoxLayout(self.otherGroupBox) self.otherGroupBox.setLayout(self.otherGroupBoxLayout) self.repetitionsLabel = QLabel("Repetitions") self.repetitionsSpinBox = QSpinBox( minimum=0, maximum=10000, value=0, sizePolicy=self.size_policy, specialValueText="∞", ) self.modeLabel = QLabel("Mode") self.modeComboBox = QComboBox(sizePolicy=self.size_policy) self.modeComboBox.addItems(["work", "rest"]) self.otherGroupBoxLayout.addWidget(self.repetitionsLabel) self.otherGroupBoxLayout.addWidget(self.repetitionsSpinBox) self.otherGroupBoxLayout.addWidget(self.modeLabel) self.otherGroupBoxLayout.addWidget(self.modeComboBox) """ Create timer groupbox""" self.lcdDisplayGroupBox = QGroupBox("Time") self.lcdDisplayGroupBoxLayout = QHBoxLayout(self.lcdDisplayGroupBox) self.lcdDisplayGroupBox.setLayout(self.lcdDisplayGroupBoxLayout) self.timeDisplay = QLCDNumber(8, sizePolicy=self.size_policy) self.timeDisplay.setFixedHeight(100) self.timeDisplay.display("00:00:00") self.lcdDisplayGroupBoxLayout.addWidget(self.timeDisplay) """ Create pause, start and reset buttons""" self.buttonContainer = QWidget() self.buttonContainerLayout = QHBoxLayout(self.buttonContainer) self.buttonContainer.setLayout(self.buttonContainerLayout) self.startButton = self.makeButton("start", disabled=False) self.resetButton = self.makeButton("reset") self.pauseButton = self.makeButton("pause") """ Add widgets to container """ self.workGroupBoxLayout.addWidget(self.workHoursSpinBox) self.workGroupBoxLayout.addWidget(self.workMinutesSpinBox) self.workGroupBoxLayout.addWidget(self.workSecondsSpinBox) self.timerContainerLayout.addWidget(self.workGroupBox) self.timerContainerLayout.addWidget(self.restGroupBox) self.timerContainerLayout.addWidget(self.otherGroupBox) self.timerContainerLayout.addWidget(self.lcdDisplayGroupBox) self.buttonContainerLayout.addWidget(self.pauseButton) self.buttonContainerLayout.addWidget(self.startButton) self.buttonContainerLayout.addWidget(self.resetButton) self.timerContainerLayout.addWidget(self.buttonContainer) return self.timerContainer def setupTasksTab(self): settings = QSettings() """ Create vertical tasks container """ self.tasksWidget = QWidget(self.tabWidget) self.tasksWidgetLayout = QVBoxLayout(self.tasksWidget) self.tasksWidget.setLayout(self.tasksWidgetLayout) """ Create horizontal input container """ self.inputContainer = QWidget() self.inputContainer.setFixedHeight(50) self.inputContainerLayout = QHBoxLayout(self.inputContainer) self.inputContainerLayout.setContentsMargins(0, 0, 0, 0) self.inputContainer.setLayout(self.inputContainerLayout) """ Create text edit """ self.taskTextEdit = QTextEdit( placeholderText="Describe your task briefly.", undoRedoEnabled=True) """ Create vertical buttons container """ self.inputButtonContainer = QWidget() self.inputButtonContainerLayout = QVBoxLayout( self.inputButtonContainer) self.inputButtonContainerLayout.setContentsMargins(0, 0, 0, 0) self.inputButtonContainer.setLayout(self.inputButtonContainerLayout) """ Create buttons """ self.acceptTaskButton = QToolButton(icon=makeIcon("check")) self.deleteTaskButton = QToolButton(icon=makeIcon("trash")) """ Create tasks tablewidget """ self.tasksTableWidget = QTableWidget(0, 1) self.tasksTableWidget.setHorizontalHeaderLabels(["Tasks"]) self.tasksTableWidget.horizontalHeader().setStretchLastSection(True) self.tasksTableWidget.verticalHeader().setVisible(False) self.tasksTableWidget.setWordWrap(True) self.tasksTableWidget.setTextElideMode(Qt.TextElideMode.ElideNone) self.tasksTableWidget.setEditTriggers( QAbstractItemView.EditTriggers.NoEditTriggers) self.tasksTableWidget.setSelectionMode( QAbstractItemView.SelectionMode.SingleSelection) self.insertTasks(*settings.value(tasksKey, [])) """ Add widgets to container widgets """ self.inputButtonContainerLayout.addWidget(self.acceptTaskButton) self.inputButtonContainerLayout.addWidget(self.deleteTaskButton) self.inputContainerLayout.addWidget(self.taskTextEdit) self.inputContainerLayout.addWidget(self.inputButtonContainer) self.tasksWidgetLayout.addWidget(self.inputContainer) self.tasksWidgetLayout.addWidget(self.tasksTableWidget) return self.tasksWidget def setupStatisticsTab(self): """ Create statistics container """ self.statisticsContainer = QWidget() self.statisticsContainerLayout = QVBoxLayout(self.statisticsContainer) self.statisticsContainer.setLayout(self.statisticsContainerLayout) """ Create work time groupbox """ self.statisticsWorkTimeGroupBox = QGroupBox("Work Time") self.statisticsWorkTimeGroupBoxLayout = QHBoxLayout() self.statisticsWorkTimeGroupBox.setLayout( self.statisticsWorkTimeGroupBoxLayout) self.statisticsWorkTimeDisplay = QLCDNumber(8) self.statisticsWorkTimeDisplay.display("00:00:00") self.statisticsWorkTimeGroupBoxLayout.addWidget( self.statisticsWorkTimeDisplay) """ Create rest time groupbox """ self.statisticsRestTimeGroupBox = QGroupBox("Rest Time") self.statisticsRestTimeGroupBoxLayout = QHBoxLayout() self.statisticsRestTimeGroupBox.setLayout( self.statisticsRestTimeGroupBoxLayout) self.statisticsRestTimeDisplay = QLCDNumber(8) self.statisticsRestTimeDisplay.display("00:00:00") self.statisticsRestTimeGroupBoxLayout.addWidget( self.statisticsRestTimeDisplay) """ Create total time groupbox """ self.statisticsTotalTimeGroupBox = QGroupBox("Total Time") self.statisticsTotalTimeGroupBoxLayout = QHBoxLayout() self.statisticsTotalTimeGroupBox.setLayout( self.statisticsTotalTimeGroupBoxLayout) self.statisticsTotalTimeDisplay = QLCDNumber(8) self.statisticsTotalTimeDisplay.display("00:00:00") self.statisticsTotalTimeGroupBoxLayout.addWidget( self.statisticsTotalTimeDisplay) """ Add widgets to container """ self.statisticsContainerLayout.addWidget( self.statisticsTotalTimeGroupBox) self.statisticsContainerLayout.addWidget( self.statisticsWorkTimeGroupBox) self.statisticsContainerLayout.addWidget( self.statisticsRestTimeGroupBox) return self.statisticsContainer def setupTrayicon(self): self.trayIcon = QSystemTrayIcon(makeIcon("tomato")) self.trayIcon.setContextMenu(QMenu()) self.quitAction = self.trayIcon.contextMenu().addAction( makeIcon("exit"), "Quit", self.exit) self.quitAction.triggered.connect(self.exit) self.trayIcon.activated.connect(self.onActivate) self.trayIcon.show() self.trayIcon.setToolTip("Pomodoro") self.toast = ToastNotifier() def leaveEvent(self, event): super(MainWindow, self).leaveEvent(event) self.tasksTableWidget.clearSelection() def closeEvent(self, event): super(MainWindow, self).closeEvent(event) settings = QSettings() settings.setValue(workHoursKey, self.workHoursSpinBox.value()) settings.setValue( workMinutesKey, self.workMinutesSpinBox.value(), ) settings.setValue( workSecondsKey, self.workSecondsSpinBox.value(), ) settings.setValue(restHoursKey, self.restHoursSpinBox.value()) settings.setValue( restMinutesKey, self.restMinutesSpinBox.value(), ) settings.setValue( restSecondsKey, self.restSecondsSpinBox.value(), ) tasks = [] for i in range(self.tasksTableWidget.rowCount()): item = self.tasksTableWidget.item(i, 0) if not item.font().strikeOut(): tasks.append(item.text()) settings.setValue(tasksKey, tasks) def startTimer(self): try: if not self.timer.isActive(): self.createTimer() except: self.createTimer() def createTimer(self): self.timer = QTimer() self.timer.timeout.connect(self.updateTime) self.timer.timeout.connect(self.maybeChangeMode) self.timer.setInterval(1000) self.timer.setSingleShot(False) self.timer.start() def pauseTimer(self): try: self.timer.stop() self.timer.disconnect() except: pass def resetTimer(self): try: self.pauseTimer() self.time = QTime(0, 0, 0, 0) self.displayTime() except: pass def maybeStartTimer(self): if self.currentRepetitions != self.maxRepetitions: self.startTimer() started = True else: self.currentRepetitions = 0 started = False return started def updateWorkEndTime(self): self.workEndTime = QTime( self.workHoursSpinBox.value(), self.workMinutesSpinBox.value(), self.workSecondsSpinBox.value(), ) def updateRestEndTime(self): self.restEndTime = QTime( self.restHoursSpinBox.value(), self.restMinutesSpinBox.value(), self.restSecondsSpinBox.value(), ) def updateCurrentMode(self, mode: str): self.currentMode = Mode.work if mode == "work" else Mode.rest def updateTime(self): self.time = self.time.addSecs(1) self.totalTime = self.totalTime.addSecs(1) if self.modeComboBox.currentText() == "work": self.workTime = self.workTime.addSecs(1) else: self.restTime = self.restTime.addSecs(1) self.displayTime() def updateMaxRepetitions(self, value): if value == 0: self.currentRepetitions = 0 self.maxRepetitions = -1 else: self.maxRepetitions = 2 * value def maybeChangeMode(self): if self.currentMode is Mode.work and self.time >= self.workEndTime: self.resetTimer() self.modeComboBox.setCurrentIndex(1) self.incrementCurrentRepetitions() started = self.maybeStartTimer() self.showWindowMessage( Status.workFinished if started else Status.repetitionsReached) if not started: self.resetButton.click() elif self.currentMode is Mode.rest and self.time >= self.restEndTime: self.resetTimer() self.modeComboBox.setCurrentIndex(0) self.incrementCurrentRepetitions() started = self.maybeStartTimer() self.showWindowMessage( Status.restFinished if started else Status.repetitionsReached) if not started: self.resetButton.click() def incrementCurrentRepetitions(self): if self.maxRepetitions > 0: self.currentRepetitions += 1 def insertTask(self): task = self.taskTextEdit.toPlainText() self.insertTasks(task) def insertTasks(self, *tasks): for task in tasks: if task: rowCount = self.tasksTableWidget.rowCount() self.tasksTableWidget.setRowCount(rowCount + 1) self.tasksTableWidget.setItem(rowCount, 0, QTableWidgetItem(task)) self.tasksTableWidget.resizeRowsToContents() self.taskTextEdit.clear() def deleteTask(self): selectedIndexes = self.tasksTableWidget.selectedIndexes() if selectedIndexes: self.tasksTableWidget.removeRow(selectedIndexes[0].row()) def markTaskAsFinished(self, row, col): item = self.tasksTableWidget.item(row, col) font = self.tasksTableWidget.item(row, col).font() font.setStrikeOut(False if item.font().strikeOut() else True) item.setFont(font) def displayTime(self): self.timeDisplay.display(self.time.toString(self.timeFormat)) self.statisticsRestTimeDisplay.display( self.restTime.toString(self.timeFormat)) self.statisticsWorkTimeDisplay.display( self.workTime.toString(self.timeFormat)) self.statisticsTotalTimeDisplay.display( self.totalTime.toString(self.timeFormat)) def showWindowMessage(self, status): if status is Status.workFinished: title, text = "Break", choice(work_finished_phrases) elif status is Status.restFinished: title, text = "Work", choice(rest_finished_phrases) else: title, text = "Finished", choice(work_finished_phrases) self.trayIcon.showMessage(title, text, makeIcon("tomato")) self.toast.show_toast(title, text, icon_path="pomodoro/data/icons/tomato.ico", duration=10, threaded=True) def makeButton(self, text, iconName=None, disabled=True): button = QPushButton(text, sizePolicy=self.size_policy) if iconName: button.setIcon(makeIcon(iconName)) button.setDisabled(disabled) return button def exit(self): self.close() app = QApplication.instance() if app: app.quit() def onActivate(self, reason): if reason == QSystemTrayIcon.ActivationReason.Trigger: self.show()
class MyMainWindow(QMainWindow, Ui_fgoMainWindow): signalFuncBegin = pyqtSignal() signalFuncEnd = pyqtSignal(object) def __init__(self, parent=None): super().__init__(parent) self.setupUi(self) self.TRAY = QSystemTrayIcon(self) self.TRAY.setIcon(QApplication.style().standardIcon( QStyle.StandardPixmap.SP_MessageBoxInformation)) self.TRAY.setToolTip('FGO-py') self.MENU_TRAY = QMenu(self) self.MENU_TRAY_QUIT = QAction('退出', self.MENU_TRAY) self.MENU_TRAY.addAction(self.MENU_TRAY_QUIT) self.MENU_TRAY_FORCEQUIT = QAction('强制退出', self.MENU_TRAY) self.MENU_TRAY.addAction(self.MENU_TRAY_FORCEQUIT) self.TRAY.setContextMenu(self.MENU_TRAY) self.TRAY.show() self.reloadTeamup() self.config = Config({ 'stopOnDefeated': (self.MENU_SETTINGS_DEFEATED, fgoKernel.schedule.stopOnDefeated), 'stopOnKizunaReisou': (self.MENU_SETTINGS_KIZUNAREISOU, fgoKernel.schedule.stopOnKizunaReisou), 'closeToTray': (self.MENU_CONTROL_TRAY, None), 'stayOnTop': (self.MENU_CONTROL_STAYONTOP, lambda x: self.setWindowFlag( Qt.WindowType.WindowStaysOnTopHint, x)), 'notifyEnable': (self.MENU_CONTROL_NOTIFY, None) }) self.notifier = ServerChann(**self.config['notifyParam']) self.worker = Thread() self.signalFuncBegin.connect(self.funcBegin) self.signalFuncEnd.connect(self.funcEnd) self.TRAY.activated.connect(lambda reason: self.show( ) if reason == QSystemTrayIcon.ActivationReason.Trigger else None) self.MENU_TRAY_QUIT.triggered.connect(lambda: QApplication.quit() if self.askQuit() else None) self.MENU_TRAY_FORCEQUIT.triggered.connect(QApplication.quit) self.getDevice() def keyPressEvent(self, key): if self.MENU_CONTROL_MAPKEY.isChecked( ) and not key.modifiers() & ~Qt.KeyboardModifier.KeypadModifier: try: fgoKernel.device.press(chr(key.nativeVirtualKey())) except KeyError: pass except Exception as e: logger.critical(e) def closeEvent(self, event): if self.config['closeToTray']: self.hide() return event.ignore() if self.askQuit(): return event.accept() event.ignore() def askQuit(self): if self.worker.is_alive(): if QMessageBox.warning( self, 'FGO-py', '战斗正在进行,确认关闭?', QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox. StandardButton.No) != QMessageBox.StandardButton.Yes: return False fgoKernel.schedule.stop('Quit') self.worker.join() self.TRAY.hide() self.config.save() return True def isDeviceAvailable(self): if not fgoKernel.device.available: self.LBL_DEVICE.clear() QMessageBox.critical(self, 'FGO-py', '未连接设备') return False return True def runFunc(self, func, *args, **kwargs): if not self.isDeviceAvailable(): return def f(): try: self.signalFuncBegin.emit() self.applyAll() fgoKernel.schedule.reset() fgoKernel.fuse.reset() func(*args, **kwargs) except fgoKernel.ScriptTerminate as e: logger.critical(e) msg = (str(e), QSystemTrayIcon.MessageIcon.Warning) except BaseException as e: logger.exception(e) msg = (repr(e), QSystemTrayIcon.MessageIcon.Critical) else: msg = ('Done', QSystemTrayIcon.MessageIcon.Information) finally: self.signalFuncEnd.emit(msg) if self.config['notifyEnable'] and not self.notifier(msg[0]): logger.critical('Notify post failed') self.worker = Thread( target=f, name= f'{getattr(func,"__qualname__",getattr(type(func),"__qualname__",repr(func)))}({",".join(repr(i)for i in args)}{","if kwargs else""}{",".join("%s=%r"%i for i in kwargs.items())})' ) self.worker.start() def funcBegin(self): self.BTN_ONEBATTLE.setEnabled(False) self.BTN_MAIN.setEnabled(False) self.BTN_USER.setEnabled(False) self.BTN_PAUSE.setEnabled(True) self.BTN_PAUSE.setChecked(False) self.BTN_STOP.setEnabled(True) self.BTN_STOPLATER.setEnabled(True) self.MENU_SCRIPT.setEnabled(False) self.TXT_APPLE.setValue(0) def funcEnd(self, msg): self.BTN_ONEBATTLE.setEnabled(True) self.BTN_MAIN.setEnabled(True) self.BTN_USER.setEnabled(True) self.BTN_PAUSE.setEnabled(False) self.BTN_STOP.setEnabled(False) self.BTN_STOPLATER.setChecked(False) self.BTN_STOPLATER.setEnabled(False) self.MENU_SCRIPT.setEnabled(True) self.TRAY.showMessage('FGO-py', *msg) def loadTeam(self, teamName): self.TXT_TEAM.setValue(int(self.teamup[teamName]['teamIndex'])) (lambda skillInfo: [ getattr(self, f'TXT_SKILL_{i}_{j}_{k}').setValue(skillInfo[i][j][ k]) for i in range(6) for j in range(3) for k in range(4) ])(eval(self.teamup[teamName]['skillInfo'])) (lambda houguInfo: [ getattr(self, f'TXT_HOUGU_{i}_{j}').setValue(houguInfo[i][j]) for i in range(6) for j in range(2) ])(eval(self.teamup[teamName]['houguInfo'])) (lambda masterSkill: [ getattr(self, f'TXT_MASTER_{i}_{j}').setValue(masterSkill[i][j]) for i in range(3) for j in range(4 + (i == 2)) ])(eval(self.teamup[teamName]['masterSkill'])) def saveTeam(self): if not self.CBX_TEAM.currentText(): return self.teamup[self.CBX_TEAM.currentText()] = { 'teamIndex': self.TXT_TEAM.value(), 'skillInfo': str([[[ getattr(self, f'TXT_SKILL_{i}_{j}_{k}').value() for k in range(4) ] for j in range(3)] for i in range(6)]).replace(' ', ''), 'houguInfo': str([[ getattr(self, f'TXT_HOUGU_{i}_{j}').value() for j in range(2) ] for i in range(6)]).replace(' ', ''), 'masterSkill': str([[ getattr(self, f'TXT_MASTER_{i}_{j}').value() for j in range(4 + (i == 2)) ] for i in range(3)]).replace(' ', '') } with open('fgoTeamup.ini', 'w') as f: self.teamup.write(f) def resetTeam(self): self.loadTeam('DEFAULT') def getDevice(self): text, ok = QInputDialog.getItem( self, 'FGO-py', '在下拉列表中选择一个设备', l := fgoKernel.Device.enumDevices(), l.index(fgoKernel.device.name) if fgoKernel.device.name and fgoKernel.device.name in l else 0, True, Qt.WindowType.WindowStaysOnTopHint) if not ok: return fgoKernel.device = fgoKernel.Device(text) self.LBL_DEVICE.setText(fgoKernel.device.name) self.MENU_CONTROL_MAPKEY.setChecked(False) def runBattle(self): self.runFunc(fgoKernel.Battle()) def runUserScript(self): self.runFunc(fgoKernel.UserScript()) def runMain(self): text, ok = QInputDialog.getItem(self, '肝哪个', '在下拉列表中选择战斗函数', ['完成战斗', '用户脚本'], 0, False) if ok and text: self.runFunc( fgoKernel.Main(self.TXT_APPLE.value(), self.CBX_APPLE.currentIndex(), { '完成战斗': fgoKernel.Battle, '用户脚本': fgoKernel.UserScript }[text])) def pause(self, x): if not x and not self.isDeviceAvailable(): return self.BTN_PAUSE.setChecked(True) fgoKernel.schedule.pause() def stop(self): fgoKernel.schedule.stop('Terminate Command Effected') def stopLater(self, x): if x: num, ok = QInputDialog.getInt(self, '输入', '剩余的战斗数量', 1, 1, 1919810, 1) if ok: fgoKernel.schedule.stopLater(num) else: self.BTN_STOPLATER.setChecked(False) else: fgoKernel.schedule.stopLater() def checkScreenshot(self): if not self.isDeviceAvailable(): return try: fgoKernel.Detect(0, blockFuse=True).show() except Exception as e: logger.exception(e) def applyAll(self): fgoKernel.Main.teamIndex = self.TXT_TEAM.value() fgoKernel.Turn.skillInfo = [[[ getattr(self, f'TXT_SKILL_{i}_{j}_{k}').value() for k in range(4) ] for j in range(3)] for i in range(6)] fgoKernel.Turn.houguInfo = [[ getattr(self, f'TXT_HOUGU_{i}_{j}').value() for j in range(2) ] for i in range(6)] fgoKernel.Turn.masterSkill = [[ getattr(self, f'TXT_MASTER_{i}_{j}').value() for j in range(4 + (i == 2)) ] for i in range(3)] def explorerHere(self): os.startfile('.') def runGacha(self): self.runFunc(fgoKernel.gacha) def runJackpot(self): self.runFunc(fgoKernel.jackpot) def runMail(self): self.runFunc(fgoKernel.mail) def runSynthesis(self): self.runFunc(fgoKernel.synthesis) def stopOnDefeated(self, x): self.config['stopOnDefeated'] = x def stopOnKizunaReisou(self, x): self.config['stopOnKizunaReisou'] = x def stopOnSpecialDrop(self): num, ok = QInputDialog.getInt(self, '输入', '剩余的特殊掉落数量', 1, 0, 1919810, 1) if ok: fgoKernel.schedule.stopOnSpecialDrop(num) def stayOnTop(self, x): self.config['stayOnTop'] = x self.show() def closeToTray(self, x): self.config['closeToTray'] = x def reloadTeamup(self): self.teamup = IniParser('fgoTeamup.ini') self.CBX_TEAM.clear() self.CBX_TEAM.addItems(self.teamup.sections()) self.CBX_TEAM.setCurrentIndex(-1) self.loadTeam('DEFAULT') def mapKey(self, x): self.MENU_CONTROL_MAPKEY.setChecked(x and self.isDeviceAvailable()) def invoke169(self): if not self.isDeviceAvailable(): return fgoKernel.device.invoke169() def revoke169(self): if not self.isDeviceAvailable(): return fgoKernel.device.revoke169() def notify(self, x): self.config['notifyEnable'] = x def exec(self): s = QApplication.clipboard().text() if QMessageBox.information( self, 'FGO-py', s, QMessageBox.StandardButton.Ok | QMessageBox. StandardButton.Cancel) != QMessageBox.StandardButton.Ok: return try: exec(s) except BaseException as e: logger.exception(e) def about(self): QMessageBox.about( self, 'FGO-py - About', f''' <h2>FGO-py</h2> FGO全自动脚本 <table border="0"> <tr><td>当前版本</td><td>{fgoKernel.__version__}</td></tr> <tr><td>作者</td><td>hgjazhgj</td></tr> <tr><td>项目地址</td><td><a href="https://github.com/hgjazhgj/FGO-py">https://github.com/hgjazhgj/FGO-py</a></td></tr> <tr><td>电子邮箱</td><td><a href="mailto:[email protected]">[email protected]</a></td></tr> <tr><td>QQ群</td><td>932481680</td></tr> </table> <!-- 都看到这里了真的不考虑资瓷一下吗... --> 这是我的<font color="#00A0E8">支付宝</font>/<font color="#22AB38">微信</font>收款码和Monero地址<br/>请给我打钱<br/> <img height="116" width="116" src="data:image/bmp;base64,Qk2yAAAAAAAAAD4AAAAoAAAAHQAAAB0AAAABAAEAAAAAAHQAAAB0EgAAdBIAAAAAAAAAAAAA6KAAAP///wABYWKofU/CKEV/ZtBFXEMwRbiQUH2a5yABj+Uo/zf3AKDtsBjeNa7YcUYb2MrQ04jEa/Ioh7TO6BR150Djjo3ATKgPmGLjdfDleznImz0gcA19mxD/rx/4AVVUAH2zpfBFCgUQRSgtEEVjdRB9/R3wATtkAA=="/> <img height="116" width="116" src="data:image/bmp;base64,Qk2yAAAAAAAAAD4AAAAoAAAAHQAAAB0AAAABAAEAAAAAAHQAAAB0EgAAdBIAAAAAAAAAAAAAOKsiAP///wABNLhYfVLBqEUYG0hFcn7gRS8QAH2Pd2ABQiVY/x1nMFWzcFhidNUwaXr3GEp1khDJzDfAuqx06ChC9hhPvmIQMJX3SCZ13ehlXB9IVtJQUAQreqj/jv/4AVVUAH0iFfBFuxUQRRAlEEX2fRB9Wl3wAdBsAA=="/> <table border="0"><tr> <td><img height="148" width="148" src="data:image/bmp;base64,Qk1mAQAAAAAAAD4AAAAoAAAAJQAAACUAAAABAAEAAAAAACgBAAB0EgAAdBIAAAAAAAAAAAAAAAAAAP///wABNpugAAAAAH0Q2oL4AAAARb1nmkAAAABFZnR3IAAAAEXpv9AwAAAAfZSA10AAAAABXdMVYAAAAP8qTsdQAAAAMd998EgAAACighiQeAAAAFCt3LiwAAAAo3aTXIAAAACAQzl8SAAAAEehYzFgAAAAcZ0FlEAAAACmEjZXoAAAAD2l77w4AAAAvy27zoAAAAD4P5FWQAAAAEYVS3VwAAAAyXKhYYAAAACvQwA4OAAAALyhfNNwAAAAhuODSLAAAABIC/+BMAAAABpa6jMwAAAA6TltfQAAAAATihl8wAAAACzQ8IxIAAAA/zQAZ/gAAAABVVVUAAAAAH0qre3wAAAARXxupRAAAABFiJ3tEAAAAEUGtG0QAAAAfWa6DfAAAAABsL3cAAAAAA=="/></td> <td><font face="Courier New">42Cnr V9Tuz E1jiS<br/>2ucGw tzN8g F6o4y<br/>9SkHs X1eZE vtiDf<br/>4QcL1 NXvfZ PhDu7<br/>LYStW rbsQM 9UUGW<br/>nqXgh ManMB dqjEW<br/>5oaDY</font></td> </tr></table> ''') def license(self): os.system( f'start notepad {"LICENSE"if os.path.isfile("LICENSE")else"../LICENSE"}' )