diff --git a/Event/__init__.py b/Event/__init__.py
index 9f5cd01..4ed8d78 100644
--- a/Event/__init__.py
+++ b/Event/__init__.py
@@ -5,7 +5,7 @@
import Event.WindowsEvents as _Event
event_cls = _Event.WindowsEvent
flag_multiplemonitor = _Event.numofmonitors > 1
-elif system() in ['Linux', 'Darwin']:
+elif system() in ['Linux', 'Darwin', 'FreeBSD']:
import Event.UniversalEvents as _Event
event_cls = _Event.UniversalEvent
flag_multiplemonitor = False
diff --git a/README.md b/README.md
index 168ab5f..acd5731 100644
--- a/README.md
+++ b/README.md
@@ -167,6 +167,8 @@ chmod -R 770 ~/.qt_material
如果您是开发爱好者,并对本项目感兴趣,欢迎参与项目的共同建设,您可以通过本项目的[**dev**](https://github.com/taojy123/KeymouseGo/tree/dev)分支查看目前的进度,并且可以向本项目的[**dev**](https://github.com/taojy123/KeymouseGo/tree/dev)分支提交 Pull request 来贡献代码。
+注:如果您需要修改应用界面,请修改UIView.ui文件并通过pyuic生成UIVIew.py,控件的初始化等操作请添加到UIFunc.py内。
+
感谢 JetBrains 免费提供开发工具
diff --git a/README_en-US.md b/README_en-US.md
index ec85304..d813289 100644
--- a/README_en-US.md
+++ b/README_en-US.md
@@ -177,6 +177,9 @@ My Email: taojy123@163.com
If you are a developer and interested in this project, you can check the progress in branch [**dev**](https://github.com/taojy123/KeymouseGo/tree/dev). and you are welcomed to participating by opening pull request to branch [**dev**](https://github.com/taojy123/KeymouseGo/tree/dev).
+注:如果您需要修改应用界面,请修改UIView.ui文件并通过pyuic生成UIVIew.py,控件的初始化等操作请添加到UIFunc.py内。
+Note: If you want to modify the application UI, please modify `UIView.ui` and generate `UIView.py` via `pyuic`. Then add the widget initialization operation in `UIFunc.py`.
+
Thanks to free develop tool provided by JetBrains
diff --git a/Recorder/__init__.py b/Recorder/__init__.py
index 7d47501..2fe2f02 100644
--- a/Recorder/__init__.py
+++ b/Recorder/__init__.py
@@ -5,7 +5,7 @@
if system() == 'Windows':
import Recorder.WindowsRecorder as _Recorder
_Recorder.globalv.key_combination_trigger = ['lwin', 'lshift', 'rshift', 'lcontrol', 'rcontrol', 'lmenu', 'rmenu']
-elif system() in ['Linux', 'Darwin']:
+elif system() in ['Linux', 'Darwin', 'FreeBSD']:
import Recorder.UniversalRecorder as _Recorder
_Recorder.globalv.key_combination_trigger = ['win', 'shiftright', 'shift', 'ctrlright', 'ctrl', 'altright', 'alt']
else:
diff --git a/UIFunc.py b/UIFunc.py
index b146a2c..26d8363 100644
--- a/UIFunc.py
+++ b/UIFunc.py
@@ -114,11 +114,13 @@ def __init__(self, app):
self.choice_theme.addItems(list_themes())
# self.choice_theme.addItems(PluginManager.resources_paths)
self.stimes.setValue(int(self.config.value("Config/LoopTimes")))
+ self.interval.setValue(int(self.config.value("Config/Interval")))
self.mouse_move_interval_ms.setValue(int(self.config.value("Config/Precision")))
self.choice_theme.setCurrentText(self.config.value("Config/Theme"))
if self.config.value('Config/Script') is not None and self.config.value('Config/Script') in self.scripts:
self.choice_script.setCurrentText(self.config.value('Config/Script'))
self.stimes.valueChanged.connect(self.onconfigchange)
+ self.interval.valueChanged.connect(self.onconfigchange)
self.mouse_move_interval_ms.valueChanged.connect(self.onconfigchange)
self.mouse_move_interval_ms.valueChanged.connect(Recorder.set_interval)
self.choice_theme.currentTextChanged.connect(self.onchangetheme)
@@ -126,7 +128,56 @@ def __init__(self, app):
self.hotkey_stop.setText(self.config.value("Config/StopHotKey"))
self.hotkey_start.setText(self.config.value("Config/StartHotKey"))
self.hotkey_record.setText(self.config.value("Config/RecordHotKey"))
-
+ start_time_config = self.config.value("Config/StartTime", "不定时")
+ if start_time_config == "不定时":
+ self.checkbox_no_timing_start.setChecked(True)
+ else:
+ hour, minute, _ = start_time_config.split(":")
+ self.combo_start_hour.setCurrentText(hour)
+ self.combo_start_min.setCurrentText(minute)
+ self.combo_start_hour.currentTextChanged.connect(self.onconfigchange)
+ self.combo_start_min.currentTextChanged.connect(self.onconfigchange)
+ stop_time_config = self.config.value("Config/StopTime", "不定时")
+ if stop_time_config == "不定时":
+ self.checkbox_no_timing_stop.setChecked(True)
+ else:
+ hour, minute, _ = stop_time_config.split(":")
+ self.combo_stop_hour.setCurrentText(hour)
+ self.combo_stop_min.setCurrentText(minute)
+ self.combo_stop_hour.currentTextChanged.connect(self.onconfigchange)
+ self.combo_stop_min.currentTextChanged.connect(self.onconfigchange)
+ self.timer = QTimer(self)
+ self.timer.timeout.connect(self.check_time)
+ self.timer.start(1000) # 每秒检查一次时间
+ self.last_start_triggered = None # 记录最后一次启动触发时间(格式:"HH:MM")
+ self.last_stop_triggered = None # 记录最后一次停止触发时间
+
+ self.checkbox_no_timing_start.stateChanged.connect(
+ lambda: self._toggle_time_controls(
+ self.checkbox_no_timing_start,
+ self.combo_start_hour,
+ self.combo_start_min
+ )
+ )
+ self.checkbox_no_timing_stop.stateChanged.connect(
+ lambda: self._toggle_time_controls(
+ self.checkbox_no_timing_stop,
+ self.combo_stop_hour,
+ self.combo_stop_min
+ )
+ )
+
+ # 初始化时根据配置设置控件状态
+ self._toggle_time_controls(
+ self.checkbox_no_timing_start,
+ self.combo_start_hour,
+ self.combo_start_min
+ )
+ self._toggle_time_controls(
+ self.checkbox_no_timing_stop,
+ self.combo_stop_hour,
+ self.combo_stop_min
+ )
self.onchangetheme()
@@ -282,12 +333,23 @@ def eventFilter(self, watched, event: QEvent):
def onconfigchange(self):
self.config.setValue("Config/LoopTimes", self.stimes.value())
+ self.config.setValue("Config/Interval", self.interval.value())
self.config.setValue("Config/Precision", self.mouse_move_interval_ms.value())
self.config.setValue("Config/Theme", self.choice_theme.currentText())
self.config.setValue("Config/Script", self.choice_script.currentText())
self.config.setValue("Config/StartHotKey", self.hotkey_start.text())
self.config.setValue("Config/StopHotKey", self.hotkey_stop.text())
self.config.setValue("Config/RecordHotKey", self.hotkey_record.text())
+ if self.checkbox_no_timing_start.isChecked():
+ start_time = "不定时"
+ else:
+ start_time = f"{self.combo_start_hour.currentText()}:{self.combo_start_min.currentText()}:00"
+ self.config.setValue("Config/StartTime", start_time)
+ if self.checkbox_no_timing_stop.isChecked():
+ stop_time = "不定时"
+ else:
+ stop_time = f"{self.combo_stop_hour.currentText()}:{self.combo_stop_min.currentText()}:00"
+ self.config.setValue("Config/StopTime", stop_time)
def onchangelang(self):
global scripts_map
@@ -344,6 +406,7 @@ def loadconfig(self):
'StopHotKey=f9\n'
'RecordHotKey=f10\n'
'LoopTimes=1\n'
+ 'Interval=0\n'
'Precision=200\n'
'Language=zh-cn\n'
'Theme=Default\n')
@@ -483,3 +546,34 @@ def handle_runscript_status(self, succeed):
@Slot(tuple)
def cursor_pos_change(self, pos):
self.label_cursor_pos.setText(f'Cursor pos: {pos}')
+
+ def check_time(self):
+ current_time = datetime.datetime.now().strftime("%H:%M") # 仅比较小时和分钟
+ if self.checkbox_no_timing_start.isChecked():
+ start_time = "不定时"
+ else:
+ start_time = f"{self.combo_start_hour.currentText()}:{self.combo_start_min.currentText()}"
+
+ if self.checkbox_no_timing_stop.isChecked():
+ stop_time = "不定时"
+ else:
+ stop_time = f"{self.combo_stop_hour.currentText()}:{self.combo_stop_min.currentText()}"
+
+ if start_time != "不定时" and current_time == start_time and self.state == State.IDLE and self.last_start_triggered != current_time:
+ self.OnBtrunButton()
+ self.last_start_triggered = current_time
+
+ if stop_time != "不定时" and current_time == stop_time and (self.state == State.RUNNING or self.state == State.PAUSE_RUNNING) and self.last_stop_triggered != current_time:
+ self.tnumrd.setText('broken')
+ if self.runthread:
+ self.runthread.resume()
+ self.update_state(State.IDLE)
+ self.last_stop_triggered = current_time
+
+ def _toggle_time_controls(self, checkbox, combo_hour, combo_min):
+ if checkbox.isChecked():
+ combo_hour.setEnabled(False)
+ combo_min.setEnabled(False)
+ else:
+ combo_hour.setEnabled(True)
+ combo_min.setEnabled(True)
diff --git a/UIView.py b/UIView.py
index 780497f..4c1f2ac 100644
--- a/UIView.py
+++ b/UIView.py
@@ -19,7 +19,7 @@
QGroupBox, QHBoxLayout, QLabel, QLayout,
QMainWindow, QMenuBar, QPushButton, QSizePolicy,
QSlider, QSpinBox, QStatusBar, QTextEdit,
- QVBoxLayout, QWidget)
+ QVBoxLayout, QWidget, QCheckBox)
import assets_rc
class Ui_UIView(object):
@@ -167,23 +167,6 @@ def setupUi(self, UIView):
self.gridLayout_4 = QGridLayout(self.groupBox_2)
self.gridLayout_4.setObjectName(u"gridLayout_4")
self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
- self.choice_theme = QComboBox(self.groupBox_2)
- self.choice_theme.setObjectName(u"choice_theme")
- sizePolicy.setHeightForWidth(self.choice_theme.sizePolicy().hasHeightForWidth())
- self.choice_theme.setSizePolicy(sizePolicy)
-
- self.gridLayout_4.addWidget(self.choice_theme, 3, 1, 1, 1)
-
- self.label_execute_interval = QLabel(self.groupBox_2)
- self.label_execute_interval.setObjectName(u"label_execute_interval")
-
- self.gridLayout_4.addWidget(self.label_execute_interval, 2, 0, 1, 1)
-
- self.label_theme = QLabel(self.groupBox_2)
- self.label_theme.setObjectName(u"label_theme")
-
- self.gridLayout_4.addWidget(self.label_theme, 3, 0, 1, 1)
-
self.mouse_move_interval_ms = QSpinBox(self.groupBox_2)
self.mouse_move_interval_ms.setObjectName(u"mouse_move_interval_ms")
sizePolicy.setHeightForWidth(self.mouse_move_interval_ms.sizePolicy().hasHeightForWidth())
@@ -192,7 +175,7 @@ def setupUi(self, UIView):
self.mouse_move_interval_ms.setMaximum(1000)
self.mouse_move_interval_ms.setValue(100)
- self.gridLayout_4.addWidget(self.mouse_move_interval_ms, 2, 1, 1, 1)
+ self.gridLayout_4.addWidget(self.mouse_move_interval_ms, 3, 1, 1, 1)
self.gridLayout = QGridLayout()
self.gridLayout.setObjectName(u"gridLayout")
@@ -216,10 +199,15 @@ def setupUi(self, UIView):
self.gridLayout_4.addLayout(self.gridLayout, 0, 1, 1, 1)
- self.label_script = QLabel(self.groupBox_2)
- self.label_script.setObjectName(u"label_script")
+ self.label_execute_interval = QLabel(self.groupBox_2)
+ self.label_execute_interval.setObjectName(u"label_execute_interval")
- self.gridLayout_4.addWidget(self.label_script, 0, 0, 1, 1)
+ self.gridLayout_4.addWidget(self.label_execute_interval, 3, 0, 1, 1)
+
+ self.label_theme = QLabel(self.groupBox_2)
+ self.label_theme.setObjectName(u"label_theme")
+
+ self.gridLayout_4.addWidget(self.label_theme, 4, 0, 1, 1)
self.label_run_times = QLabel(self.groupBox_2)
self.label_run_times.setObjectName(u"label_run_times")
@@ -235,15 +223,87 @@ def setupUi(self, UIView):
self.gridLayout_4.addWidget(self.stimes, 1, 1, 1, 1)
+ self.choice_theme = QComboBox(self.groupBox_2)
+ self.choice_theme.setObjectName(u"choice_theme")
+ sizePolicy.setHeightForWidth(self.choice_theme.sizePolicy().hasHeightForWidth())
+ self.choice_theme.setSizePolicy(sizePolicy)
+
+ self.gridLayout_4.addWidget(self.choice_theme, 4, 1, 1, 1)
+
+ self.label_script = QLabel(self.groupBox_2)
+ self.label_script.setObjectName(u"label_script")
+
+ self.gridLayout_4.addWidget(self.label_script, 0, 0, 1, 1)
+
+ self.label_interval = QLabel(self.groupBox_2)
+ self.label_interval.setObjectName(u"label_interval")
+
+ self.gridLayout_4.addWidget(self.label_interval, 2, 0, 1, 1)
+
+ self.interval = QSpinBox(self.groupBox_2)
+ self.interval.setObjectName(u"interval")
+ sizePolicy.setHeightForWidth(self.interval.sizePolicy().hasHeightForWidth())
+ self.interval.setSizePolicy(sizePolicy)
+ self.interval.setMaximum(1000000000)
+
+ self.gridLayout_4.addWidget(self.interval, 2, 1, 1, 1)
+
UIView.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(UIView)
self.menubar.setObjectName(u"menubar")
- self.menubar.setGeometry(QRect(0, 0, 651, 24))
+ self.menubar.setGeometry(QRect(0, 0, 651, 21))
UIView.setMenuBar(self.menubar)
self.statusbar = QStatusBar(UIView)
self.statusbar.setObjectName(u"statusbar")
UIView.setStatusBar(self.statusbar)
+ # 定时开始时间的小时和分钟选择
+ self.label_start_time = QLabel(self.groupBox)
+ self.label_start_time.setText("定时开始时间:")
+ self.combo_start_hour = QComboBox(self.groupBox)
+ self.combo_start_min = QComboBox(self.groupBox)
+ for hour in range(24):
+ self.combo_start_hour.addItem(f"{hour:02d}")
+ for minute in range(0, 60, 1):
+ self.combo_start_min.addItem(f"{minute:02d}")
+ self.combo_start_hour.setCurrentText("00")
+ self.combo_start_min.setCurrentText("00")
+
+ # 定时停止时间的小时和分钟选择
+ self.label_stop_time = QLabel(self.groupBox)
+ self.label_stop_time.setText("定时停止时间:")
+ self.combo_stop_hour = QComboBox(self.groupBox)
+ self.combo_stop_min = QComboBox(self.groupBox)
+ for hour in range(24):
+ self.combo_stop_hour.addItem(f"{hour:02d}")
+ for minute in range(0, 60, 1):
+ self.combo_stop_min.addItem(f"{minute:02d}")
+ self.combo_stop_hour.setCurrentText("00")
+ self.combo_stop_min.setCurrentText("00")
+
+ # 添加“不定时”复选框
+ self.checkbox_no_timing_start = QCheckBox("不定时", self.groupBox)
+ self.checkbox_no_timing_stop = QCheckBox("不定时", self.groupBox)
+
+ # 开始时间布局
+ hbox_start = QHBoxLayout()
+ hbox_start.addWidget(self.combo_start_hour)
+ hbox_start.addWidget(QLabel(":"))
+ hbox_start.addWidget(self.combo_start_min)
+ hbox_start.addWidget(self.checkbox_no_timing_start)
+
+ # 停止时间布局
+ hbox_stop = QHBoxLayout()
+ hbox_stop.addWidget(self.combo_stop_hour)
+ hbox_stop.addWidget(QLabel(":"))
+ hbox_stop.addWidget(self.combo_stop_min)
+ hbox_stop.addWidget(self.checkbox_no_timing_stop)
+
+ self.gridLayout_3.addWidget(self.label_start_time, 4, 0)
+ self.gridLayout_3.addLayout(hbox_start, 4, 1)
+ self.gridLayout_3.addWidget(self.label_stop_time, 5, 0)
+ self.gridLayout_3.addLayout(hbox_stop, 5, 1)
+
self.retranslateUi(UIView)
QMetaObject.connectSlotsByName(UIView)
@@ -266,10 +326,11 @@ def retranslateUi(self, UIView):
self.label_cursor_pos.setText(QCoreApplication.translate("UIView", u"Cursor Position:", None))
self.label_volume.setText(QCoreApplication.translate("UIView", u"Volume", None))
self.groupBox_2.setTitle(QCoreApplication.translate("UIView", u"Config", None))
+ self.bt_open_script_files.setText(QCoreApplication.translate("UIView", u"...", None))
self.label_execute_interval.setText(QCoreApplication.translate("UIView", u"Mouse precision", None))
self.label_theme.setText(QCoreApplication.translate("UIView", u"Theme", None))
- self.bt_open_script_files.setText(QCoreApplication.translate("UIView", u"...", None))
- self.label_script.setText(QCoreApplication.translate("UIView", u"Script", None))
self.label_run_times.setText(QCoreApplication.translate("UIView", u"Run times", None))
+ self.label_script.setText(QCoreApplication.translate("UIView", u"Script", None))
+ self.label_interval.setText(QCoreApplication.translate("UIView", u"Interval", None))
# retranslateUi
diff --git a/UIView.ui b/UIView.ui
index e782f22..af278ac 100644
--- a/UIView.ui
+++ b/UIView.ui
@@ -265,30 +265,6 @@
0
-
-
-
-
- 0
- 0
-
-
-
-
- -
-
-
- Mouse precision
-
-
-
- -
-
-
- Theme
-
-
-
- -
@@ -337,10 +313,17 @@
- -
-
+
-
+
- Script
+ Mouse precision
+
+
+
+ -
+
+
+ Theme
@@ -367,6 +350,43 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Script
+
+
+
+ -
+
+
+ Interval
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1000000000
+
+
+
@@ -376,7 +396,7 @@
0
0
651
- 24
+ 21
diff --git a/Util/RunScriptClass.py b/Util/RunScriptClass.py
index f9f1ce0..d56f976 100644
--- a/Util/RunScriptClass.py
+++ b/Util/RunScriptClass.py
@@ -47,6 +47,7 @@ def __init__(self, frame: QWidget):
self.state = State.RUNNING
self.script_path = frame.get_script_path()
self.runtimes = frame.stimes.value()
+ self.interval = frame.interval.value()
# 更新控件的槽函数
self.logSignal.connect(frame.textlog.append)
@@ -96,7 +97,7 @@ def run(self):
self.playtuneSignal.emit('end.wav')
@logger.catch
- def run_script_from_path(self, script_path: str):
+ def run_script_from_path(self, script_path: str, is_subscript: bool = False):
try:
running_text = '%s running..' % script_path.split('/')[-1].split('\\')[-1]
self.tnumrdSignal.emit(running_text)
@@ -119,12 +120,14 @@ def run_script_from_path(self, script_path: str):
j = 0
nointerrupt = True
logger.debug('Run script..')
-
- while (j < self.runtimes or self.runtimes == 0) and nointerrupt:
+ runtimes = 1 if is_subscript else self.runtimes
+ while (j < runtimes or runtimes == 0) and nointerrupt:
logger.debug('===========%d==============' % j)
+ if j > 0 and self.interval > 0:
+ self.sleep(self.interval)
if self.state == State.IDLE:
break
- self.tnumrdSignal.emit(f'{running_text}... Looptimes [{j + 1}/{self.runtimes}]')
+ self.tnumrdSignal.emit(f'{running_text}... Looptimes [{j + 1}/{runtimes}]')
nointerrupt = nointerrupt and self.run_script_from_objects(head_object)
j += 1
if nointerrupt:
@@ -185,7 +188,7 @@ def run_object(self, json_object: JsonObject):
pass
elif object_type == 'subroutine':
for path in json_object.content['path']:
- self.run_script_from_path(path)
+ self.run_script_from_path(path, True)
else:
# Not supposed to happen
logger.error(f'Unexpected event type when running {json_object.content}')
@@ -211,7 +214,7 @@ def run(self) -> None:
self.run_script_from_path(self.script_path)
@logger.catch
- def run_script_from_path(self, script_path):
+ def run_script_from_path(self, script_path, is_subscript: bool = False):
for path in script_path:
logger.info('Script path:%s' % path)
logger.debug('Parse script..')
@@ -224,7 +227,8 @@ def run_script_from_path(self, script_path):
except Exception as e:
logger.error(e)
j = 0
- while j < self.run_times or self.run_times == 0:
+ runtimes = 1 if is_subscript else self.run_times
+ while j < runtimes or runtimes == 0:
logger.info('===========%d==============' % j)
self.run_script_from_objects(head_object)
if self.flag.value:
@@ -264,7 +268,7 @@ def run_object(self, json_object: JsonObject):
elif object_type in ['goto', 'custom']:
pass
elif object_type == 'subroutine':
- self.run_script_from_path(json_object.content['path'])
+ self.run_script_from_path(json_object.content['path'], True)
else:
# Not supposed to happen
logger.error(f'Unexpected event type when running {json_object.content}')
diff --git a/archived/config.py b/archived/config.py
index 4ac0b53..178c713 100644
--- a/archived/config.py
+++ b/archived/config.py
@@ -34,6 +34,8 @@ def setdefaultconf(config):
config.set('Config', 'Precision', '200')
config.set('Config', 'ExecuteSpeed', '100')
config.set('Config', 'Language', 'zh-cn')
+ config.set('Config', 'StartTime', '不定时')
+ config.set('Config', 'StopTime', '不定时')
def getconfig():
if not os.path.exists('../config.ini'):
@@ -52,4 +54,6 @@ def saveconfig(newConf):
conf.set('Config', 'Precision', str(newConf['precision']))
conf.set('Config', 'ExecuteSpeed', str(newConf['executespeed']))
conf.set('Config', 'Language', str(newConf['language']))
+ conf.set('Config', 'StartTime', newConf.get('start_time', '不定时'))
+ conf.set('Config', 'StopTime', newConf.get('stop_time', '不定时'))
conf.write(open('../config.ini', 'w'))