ok-script 0.0.40__tar.gz → 0.0.42__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ok-script-0.0.40 → ok-script-0.0.42}/PKG-INFO +1 -1
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/OK.py +3 -2
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/BaseCaptureMethod.py +0 -7
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/HwndWindow.py +26 -35
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/adb/DeviceManager.py +17 -9
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/windows/WindowsGraphicsCaptureMethod.py +43 -31
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/config/Config.py +36 -21
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/Communicate.py +1 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/MainWindow.py +14 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/Screenshot.py +11 -2
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/ConfigItemFactory.py +8 -8
- ok-script-0.0.42/ok/gui/tasks/ConfigLabelAndWidget.py +16 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndDoubleSpinBox.py +3 -4
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndDropDown.py +3 -4
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndLineEdit.py +3 -4
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndSpinBox.py +3 -4
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndSwitchButton.py +3 -4
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/ModifyListItem.py +12 -6
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/TaskCard.py +1 -1
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/save/SaveMethodBase.py +1 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/task/BaseTask.py +11 -1
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/task/ExecutorOperation.py +12 -4
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/task/TaskExecutor.py +1 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/exit_event.py +5 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok_script.egg-info/PKG-INFO +1 -1
- {ok-script-0.0.40 → ok-script-0.0.42}/setup.py +1 -1
- ok-script-0.0.40/ok/gui/tasks/ConfigLabelAndWidget.py +0 -10
- {ok-script-0.0.40 → ok-script-0.0.42}/README.md +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/adb/ADBCaptureMethod.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/adb/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/adb/bin/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/adb/targets.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/adb/vbox.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/windows/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/windows/d3d11.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/windows/dump.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/windows/utils.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/capture/windows/window.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/color/Color.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/color/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/config/InfoDict.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/config/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/feature/Box.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/feature/Feature.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/feature/FeatureSet.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/feature/FindFeature.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/feature/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/App.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/MessageWindow.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/TabTitles.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/about/AboutTab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/about/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/common/OKIcon.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/common/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/common/config.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/common/style_sheet.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/AspectRatioWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/DebugTab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/FrameWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/InfoWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/LoggerWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/debug/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/i18n/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/i18n/path.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/i18n/update.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/icon/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/icon/icon.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/overlay/OverlayWindow.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/overlay/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/qss/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/resources.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/settings/SettingTab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/settings/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/start/SelectCaptureListView.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/start/SelectHwndWindow.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/start/StartCard.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/start/StartTab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/start/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndList.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/LabelAndWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/ModifyListDialog.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/OneTimeTaskTab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/StartButton.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/TaskOpButton.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/TooltipTableWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/TriggerTaskTab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/tasks/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/util/Alert.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/util/InitWorker.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/util/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/Card.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/FramelessDialog.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/ListTableWidgetItem.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/NumericTableWidgetItem.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/StatusBar.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/Tab.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/TabWidget.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/UpdateConfigWidgetItem.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/YesNonWidgetItem.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/gui/widget/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/interaction/ADBInteraction.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/interaction/BaseInteraction.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/interaction/Win32Interaction.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/interaction/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/logging/Logger.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/logging/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/ocr/OCR.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/ocr/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Media/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Security/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/Storage/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/Windows/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/delegate.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/export.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/idldsl.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/inspectable.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/roapi.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/types.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/rotypes/winstring.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/save/BlackBarProcessor.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/save/PostProcessor.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/save/SaveByInterval.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/save/SaveByKeyPress.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/save/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/scene/FeatureScene.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/scene/Scene.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/scene/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/stats/StreamStats.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/stats/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/task/OneTimeTask.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/task/TriggerTask.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/task/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/__init__.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/json.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/list.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/path.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/thread.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/win32_process.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok/util/yaml.py +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok_script.egg-info/SOURCES.txt +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok_script.egg-info/dependency_links.txt +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok_script.egg-info/requires.txt +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/ok_script.egg-info/top_level.txt +0 -0
- {ok-script-0.0.40 → ok-script-0.0.42}/setup.cfg +0 -0
|
@@ -34,7 +34,7 @@ class OK:
|
|
|
34
34
|
self.config = config
|
|
35
35
|
self.init_device_manager()
|
|
36
36
|
from ok.gui.debug.Screenshot import Screenshot
|
|
37
|
-
self.screenshot = Screenshot()
|
|
37
|
+
self.screenshot = Screenshot(self.exit_event)
|
|
38
38
|
if config.get("use_gui"):
|
|
39
39
|
from ok.gui.App import App
|
|
40
40
|
self.app = App(config, self.exit_event)
|
|
@@ -123,7 +123,8 @@ class OK:
|
|
|
123
123
|
def quit(self):
|
|
124
124
|
logger.debug('quit app')
|
|
125
125
|
self.exit_event.set()
|
|
126
|
-
self.device_manager
|
|
126
|
+
if self.device_manager is not None:
|
|
127
|
+
self.device_manager.stop()
|
|
127
128
|
if self.app:
|
|
128
129
|
self.app.quit()
|
|
129
130
|
|
|
@@ -8,13 +8,6 @@ class CaptureException(Exception):
|
|
|
8
8
|
class BaseCaptureMethod:
|
|
9
9
|
name = "None"
|
|
10
10
|
description = ""
|
|
11
|
-
last_captured_frame: np.ndarray
|
|
12
|
-
top_cut = 0
|
|
13
|
-
bottom_cut = 0
|
|
14
|
-
left_cut = 0
|
|
15
|
-
right_cut = 0
|
|
16
|
-
width = 0
|
|
17
|
-
height = 0
|
|
18
11
|
_size = (0, 0)
|
|
19
12
|
|
|
20
13
|
def __init__(self):
|
|
@@ -11,7 +11,6 @@ from win32 import win32gui
|
|
|
11
11
|
from ok.capture.windows.window import is_foreground_window, get_window_bounds
|
|
12
12
|
from ok.gui.Communicate import communicate
|
|
13
13
|
from ok.logging.Logger import get_logger
|
|
14
|
-
from ok.util.exit_event import ExitEvent
|
|
15
14
|
|
|
16
15
|
logger = get_logger(__name__)
|
|
17
16
|
|
|
@@ -41,7 +40,7 @@ class HwndWindow:
|
|
|
41
40
|
super().__init__()
|
|
42
41
|
self.app_exit_event = exit_event
|
|
43
42
|
self.exe_name = exe_name
|
|
44
|
-
self.stop_event =
|
|
43
|
+
self.stop_event = threading.Event()
|
|
45
44
|
self.update_title_re(title)
|
|
46
45
|
self.visible = False
|
|
47
46
|
self.update_frame_size(frame_width, frame_height)
|
|
@@ -102,7 +101,7 @@ class HwndWindow:
|
|
|
102
101
|
visible = is_foreground_window(self.hwnd)
|
|
103
102
|
x, y, border, title_height, width, height, scaling = get_window_bounds(
|
|
104
103
|
self.hwnd)
|
|
105
|
-
if self.frame_aspect_ratio != 0:
|
|
104
|
+
if self.frame_aspect_ratio != 0 and height != 0:
|
|
106
105
|
window_ratio = width / height
|
|
107
106
|
if window_ratio < self.frame_aspect_ratio:
|
|
108
107
|
cropped_window_height = int(width / self.frame_aspect_ratio)
|
|
@@ -125,7 +124,7 @@ class HwndWindow:
|
|
|
125
124
|
changed = True
|
|
126
125
|
if changed:
|
|
127
126
|
logger.debug(
|
|
128
|
-
f"do_update_window_size changed:
|
|
127
|
+
f"do_update_window_size changed,visible:{self.visible} x:{self.x} y:{self.y} border:{self.border} width:{self.width} height:{self.height} self.title_height:{self.title_height} scaling:{self.scaling}")
|
|
129
128
|
communicate.window.emit(self.visible, self.x, self.y, self.border, self.title_height, self.width,
|
|
130
129
|
self.height, self.scaling)
|
|
131
130
|
except Exception as e:
|
|
@@ -143,37 +142,29 @@ class HwndWindow:
|
|
|
143
142
|
return ""
|
|
144
143
|
|
|
145
144
|
|
|
146
|
-
def find_hwnd_by_title_and_exe(title,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
elif re.search(title, text):
|
|
170
|
-
hwnds.append(hwnd)
|
|
171
|
-
|
|
172
|
-
win32gui.EnumWindows(enum_windows_proc, None)
|
|
173
|
-
if len(hwnds) > 0:
|
|
174
|
-
if len(hwnds) > 1:
|
|
175
|
-
logger.warning(f"Found multiple hwnds {len(hwnds)}")
|
|
176
|
-
return hwnds
|
|
145
|
+
def find_hwnd_by_title_and_exe(title, exe_name):
|
|
146
|
+
result = []
|
|
147
|
+
|
|
148
|
+
def callback(hwnd, lParam):
|
|
149
|
+
if len(result) == 0 and win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
|
|
150
|
+
if title:
|
|
151
|
+
text = win32gui.GetWindowText(hwnd)
|
|
152
|
+
if isinstance(title, str):
|
|
153
|
+
if title != text:
|
|
154
|
+
return True
|
|
155
|
+
elif not re.search(title, text):
|
|
156
|
+
return True
|
|
157
|
+
if exe_name:
|
|
158
|
+
name = get_exe_name_by_hwnd(hwnd)
|
|
159
|
+
if name == exe_name:
|
|
160
|
+
result.append(hwnd)
|
|
161
|
+
return True # Stop enumeration as we found the first match
|
|
162
|
+
else:
|
|
163
|
+
result.append(hwnd)
|
|
164
|
+
return True
|
|
165
|
+
|
|
166
|
+
win32gui.EnumWindows(callback, None)
|
|
167
|
+
return result[0] if result else None
|
|
177
168
|
|
|
178
169
|
|
|
179
170
|
OpenProcess = ctypes.windll.kernel32.OpenProcess
|
|
@@ -26,6 +26,7 @@ class DeviceManager:
|
|
|
26
26
|
self.adb = self.adb = adbutils.AdbClient(host="127.0.0.1")
|
|
27
27
|
logger.debug(f'connect adb')
|
|
28
28
|
self.hwnd_title = hwnd_title
|
|
29
|
+
self.pc_device = None
|
|
29
30
|
self.exe_name = exe_name
|
|
30
31
|
self.debug = debug
|
|
31
32
|
self.interaction = None
|
|
@@ -44,7 +45,13 @@ class DeviceManager:
|
|
|
44
45
|
|
|
45
46
|
@property
|
|
46
47
|
def device_dict(self):
|
|
47
|
-
|
|
48
|
+
device_dict = self.config.get("devices")
|
|
49
|
+
if self.pc_device is not None:
|
|
50
|
+
full = {'pc': self.pc_device}
|
|
51
|
+
full.update(device_dict)
|
|
52
|
+
return full
|
|
53
|
+
else:
|
|
54
|
+
return device_dict
|
|
48
55
|
|
|
49
56
|
def connect_all(self):
|
|
50
57
|
if not self._connect_all:
|
|
@@ -61,7 +68,6 @@ class DeviceManager:
|
|
|
61
68
|
return list(self.device_dict.values())
|
|
62
69
|
|
|
63
70
|
def do_refresh(self):
|
|
64
|
-
self.connect_all()
|
|
65
71
|
|
|
66
72
|
if self.hwnd_title:
|
|
67
73
|
nick = ""
|
|
@@ -74,16 +80,18 @@ class DeviceManager:
|
|
|
74
80
|
hwnd)
|
|
75
81
|
if not nick:
|
|
76
82
|
nick = self.exe_name
|
|
77
|
-
self.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
self.pc_device = {"address": "", "imei": 'pc', "device": "windows",
|
|
84
|
+
"model": "", "nick": nick, "width": width,
|
|
85
|
+
"height": height,
|
|
86
|
+
"hwnd": nick, "capture": "windows",
|
|
87
|
+
"connected": hwnd is not None
|
|
88
|
+
}
|
|
83
89
|
if width != 0:
|
|
84
|
-
self.
|
|
90
|
+
self.pc_device["resolution"] = f"{width}x{height}"
|
|
85
91
|
communicate.adb_devices.emit(False)
|
|
86
92
|
|
|
93
|
+
self.connect_all()
|
|
94
|
+
|
|
87
95
|
installed_emulators = installed_emulator()
|
|
88
96
|
for device in self.adb.list():
|
|
89
97
|
logger.debug(f'adb.list() {device}')
|
|
@@ -32,7 +32,7 @@ class WindowsGraphicsCaptureMethod(BaseCaptureMethod):
|
|
|
32
32
|
description = "fast, most compatible, capped at 60fps"
|
|
33
33
|
last_frame = None
|
|
34
34
|
last_frame_time = 0
|
|
35
|
-
|
|
35
|
+
_hwnd_window: HwndWindow = None
|
|
36
36
|
frame_pool = None
|
|
37
37
|
item = None
|
|
38
38
|
session = None
|
|
@@ -42,7 +42,7 @@ class WindowsGraphicsCaptureMethod(BaseCaptureMethod):
|
|
|
42
42
|
|
|
43
43
|
def __init__(self, hwnd_window: HwndWindow):
|
|
44
44
|
super().__init__()
|
|
45
|
-
self.
|
|
45
|
+
self._hwnd_window = hwnd_window
|
|
46
46
|
self.start_or_stop()
|
|
47
47
|
|
|
48
48
|
def frame_arrived_callback(self, x, y):
|
|
@@ -108,38 +108,50 @@ class WindowsGraphicsCaptureMethod(BaseCaptureMethod):
|
|
|
108
108
|
return self.get_frame()
|
|
109
109
|
self.last_frame = img
|
|
110
110
|
|
|
111
|
+
@property
|
|
112
|
+
def hwnd_window(self):
|
|
113
|
+
return self._hwnd_window
|
|
114
|
+
|
|
115
|
+
@hwnd_window.setter
|
|
116
|
+
def hwnd_window(self, hwnd_window):
|
|
117
|
+
self._hwnd_window = hwnd_window
|
|
118
|
+
self.start_or_stop()
|
|
119
|
+
|
|
111
120
|
def connected(self):
|
|
112
|
-
return self.hwnd_window is not None and self.hwnd_window.exists
|
|
121
|
+
return self.hwnd_window is not None and self.hwnd_window.exists and self.frame_pool is not None
|
|
113
122
|
|
|
114
123
|
def start_or_stop(self, capture_cursor=False):
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
self.
|
|
124
|
+
try:
|
|
125
|
+
if self.hwnd_window.exists and self.frame_pool is None:
|
|
126
|
+
logger.info('init windows capture')
|
|
127
|
+
self.rtdevice = IDirect3DDevice()
|
|
128
|
+
self.dxdevice = d3d11.ID3D11Device()
|
|
129
|
+
self.immediatedc = d3d11.ID3D11DeviceContext()
|
|
130
|
+
self.create_device()
|
|
131
|
+
interop = GetActivationFactory('Windows.Graphics.Capture.GraphicsCaptureItem').astype(
|
|
132
|
+
IGraphicsCaptureItemInterop)
|
|
133
|
+
item = interop.CreateForWindow(self.hwnd_window.hwnd, IGraphicsCaptureItem.GUID)
|
|
134
|
+
self.item = item
|
|
135
|
+
self.last_size = item.Size
|
|
136
|
+
delegate = TypedEventHandler(GraphicsCaptureItem, IInspectable).delegate(
|
|
137
|
+
self.close)
|
|
138
|
+
self.evtoken = item.add_Closed(delegate)
|
|
139
|
+
self.frame_pool = Direct3D11CaptureFramePool.CreateFreeThreaded(self.rtdevice,
|
|
140
|
+
DirectXPixelFormat.B8G8R8A8UIntNormalized,
|
|
141
|
+
1, item.Size)
|
|
142
|
+
self.session = self.frame_pool.CreateCaptureSession(item)
|
|
143
|
+
pool = self.frame_pool
|
|
144
|
+
pool.add_FrameArrived(
|
|
145
|
+
TypedEventHandler(Direct3D11CaptureFramePool, IInspectable).delegate(
|
|
146
|
+
self.frame_arrived_callback))
|
|
147
|
+
self.session.IsCursorCaptureEnabled = capture_cursor
|
|
148
|
+
if WINDOWS_BUILD_NUMBER >= WGC_NO_BORDER_MIN_BUILD:
|
|
149
|
+
self.session.IsBorderRequired = False
|
|
150
|
+
self.session.StartCapture()
|
|
151
|
+
elif not self.hwnd_window.exists and self.frame_pool is not None:
|
|
152
|
+
self.close()
|
|
153
|
+
except Exception as e:
|
|
154
|
+
logger.error('start_or_stop failed:', exception=e)
|
|
143
155
|
return self.hwnd_window.exists
|
|
144
156
|
|
|
145
157
|
def create_device(self):
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
+
from ok.gui.Communicate import communicate
|
|
1
2
|
from ok.util.json import read_json_file, write_json_file
|
|
2
3
|
from ok.util.path import get_path_relative_to_exe
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class Config:
|
|
6
|
-
def __init__(self, default, folder, name):
|
|
7
|
+
def __init__(self, default, folder, name, validator=None):
|
|
7
8
|
super().__init__()
|
|
8
9
|
self.default = default
|
|
10
|
+
self.validator = validator
|
|
9
11
|
self.config_file = get_path_relative_to_exe(folder, f"{name}.json")
|
|
10
12
|
self.config = read_json_file(self.config_file)
|
|
11
13
|
if self.config is None:
|
|
12
14
|
self.config = default
|
|
13
|
-
elif verify_config(self.config, default):
|
|
15
|
+
elif self.verify_config(self.config, default):
|
|
14
16
|
self.save_file()
|
|
15
17
|
|
|
16
18
|
def save_file(self):
|
|
@@ -60,26 +62,39 @@ class Config:
|
|
|
60
62
|
return len(self.config)
|
|
61
63
|
|
|
62
64
|
def __setitem__(self, key, value):
|
|
63
|
-
self.
|
|
64
|
-
|
|
65
|
+
if self.validate(key, value):
|
|
66
|
+
self.config[key] = value
|
|
67
|
+
self.save_file()
|
|
65
68
|
|
|
66
69
|
def __getitem__(self, key):
|
|
67
70
|
return self.config[key]
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
72
|
+
def validate(self, key, value):
|
|
73
|
+
if self.validator is not None:
|
|
74
|
+
valid, message = self.validator(key, value)
|
|
75
|
+
if not valid:
|
|
76
|
+
communicate.config_validation.emit(message)
|
|
77
|
+
return False
|
|
78
|
+
return True
|
|
79
|
+
|
|
80
|
+
def verify_config(self, config, default_config):
|
|
81
|
+
modified = False
|
|
82
|
+
|
|
83
|
+
# Remove entries that do not exist in default_config
|
|
84
|
+
for key in list(config.keys()):
|
|
85
|
+
if key not in default_config:
|
|
86
|
+
del config[key]
|
|
87
|
+
modified = True
|
|
88
|
+
|
|
89
|
+
# Check entries in default_config
|
|
90
|
+
for key, default_value in default_config.items():
|
|
91
|
+
if key not in config or type(config[key]) != type(default_value):
|
|
92
|
+
config[key] = default_value
|
|
93
|
+
modified = True
|
|
94
|
+
elif self.validator is not None:
|
|
95
|
+
valid = self.validate(key, self.config[key])
|
|
96
|
+
if not valid:
|
|
97
|
+
config[key] = default_value
|
|
98
|
+
modified = True
|
|
99
|
+
|
|
100
|
+
return not modified
|
|
@@ -67,6 +67,20 @@ class MainWindow(MSFluentWindow):
|
|
|
67
67
|
|
|
68
68
|
communicate.capture_error.connect(self.capture_error)
|
|
69
69
|
communicate.notification.connect(self.show_notification)
|
|
70
|
+
communicate.config_validation.connect(self.config_validation)
|
|
71
|
+
|
|
72
|
+
def config_validation(self, message):
|
|
73
|
+
title = self.tr('Error')
|
|
74
|
+
InfoBar.error(
|
|
75
|
+
title=title,
|
|
76
|
+
content=message,
|
|
77
|
+
orient=Qt.Horizontal,
|
|
78
|
+
isClosable=True,
|
|
79
|
+
position=InfoBarPosition.TOP,
|
|
80
|
+
duration=5000, # won't disappear automatically
|
|
81
|
+
parent=self.window()
|
|
82
|
+
)
|
|
83
|
+
self.tray.showMessage(title, message)
|
|
70
84
|
|
|
71
85
|
def show_notification(self, message, title=None, error=None):
|
|
72
86
|
bar = InfoBar.error if error else InfoBar.info
|
|
@@ -20,10 +20,9 @@ logger = get_logger(__name__)
|
|
|
20
20
|
|
|
21
21
|
class Screenshot(QObject):
|
|
22
22
|
|
|
23
|
-
def __init__(self):
|
|
23
|
+
def __init__(self, exit_event):
|
|
24
24
|
super().__init__()
|
|
25
25
|
self.queue = []
|
|
26
|
-
self.exit_event = ok.gui.ok.exit_event
|
|
27
26
|
self.time_to_expire = 3
|
|
28
27
|
self.ui_dict = {}
|
|
29
28
|
self.color_map = {
|
|
@@ -31,10 +30,13 @@ class Screenshot(QObject):
|
|
|
31
30
|
"green": QColor(0, 255, 0), # RGB for green
|
|
32
31
|
"blue": QColor(0, 0, 255) # RGB for blue
|
|
33
32
|
}
|
|
33
|
+
self.exit_event = exit_event
|
|
34
34
|
communicate.draw_box.connect(self.draw_box)
|
|
35
35
|
communicate.screenshot.connect(self.screenshot)
|
|
36
36
|
self.click_screenshot_folder = get_path_relative_to_exe(ok.gui.ok.config.get("click_screenshots_folder"))
|
|
37
37
|
self.screenshot_folder = get_path_relative_to_exe(ok.gui.ok.config.get("screenshots_folder"))
|
|
38
|
+
logger.debug(f"init Screenshot {self.screenshot_folder} {self.click_screenshot_folder}")
|
|
39
|
+
print(f"init Screenshot {self.screenshot_folder} {self.screenshot_folder}")
|
|
38
40
|
if self.click_screenshot_folder is not None or self.screenshot_folder is not None:
|
|
39
41
|
self.task_queue = queue.Queue()
|
|
40
42
|
self.exit_event.bind_queue(self.task_queue)
|
|
@@ -106,6 +108,7 @@ class Screenshot(QObject):
|
|
|
106
108
|
pil_image = self.to_pil_image(frame)
|
|
107
109
|
if pil_image is None:
|
|
108
110
|
return
|
|
111
|
+
self.save_pil_image(name + '_original', folder, pil_image)
|
|
109
112
|
# Ensure no fill
|
|
110
113
|
draw = ImageDraw.Draw(pil_image)
|
|
111
114
|
|
|
@@ -127,6 +130,11 @@ class Screenshot(QObject):
|
|
|
127
130
|
# Put text
|
|
128
131
|
draw.text((x, y + height + 8), f"{box.name or key}_{round(box.confidence * 100)}", fill=color,
|
|
129
132
|
font=self.pil_font)
|
|
133
|
+
self.save_pil_image(name + '_boxed', folder, pil_image)
|
|
134
|
+
|
|
135
|
+
def save_pil_image(self, name, folder, pil_image):
|
|
136
|
+
|
|
137
|
+
logger.debug(f'save_pil_image {name}, {folder}')
|
|
130
138
|
now = datetime.now()
|
|
131
139
|
|
|
132
140
|
# Convert to string with milliseconds
|
|
@@ -142,6 +150,7 @@ class Screenshot(QObject):
|
|
|
142
150
|
pil_image.save(os.path.join(folder, f"{time_string}.png"))
|
|
143
151
|
|
|
144
152
|
def stop(self):
|
|
153
|
+
logger.debug(f'stop screenshot')
|
|
145
154
|
if self.task_queue is not None:
|
|
146
155
|
self.task_queue.put(None)
|
|
147
156
|
|
|
@@ -6,20 +6,20 @@ from ok.gui.tasks.LabelAndSwitchButton import LabelAndSwitchButton
|
|
|
6
6
|
from ok.gui.tasks.ModifyListItem import ModifyListItem
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def config_widget(
|
|
10
|
-
the_type = config_type.get(key)
|
|
9
|
+
def config_widget(task, key, value):
|
|
10
|
+
the_type = task.config_type.get(key)
|
|
11
11
|
if the_type:
|
|
12
12
|
if the_type['type'] == 'drop_down':
|
|
13
|
-
return LabelAndDropDown(
|
|
13
|
+
return LabelAndDropDown(task, the_type['options'], key)
|
|
14
14
|
if isinstance(value, bool):
|
|
15
|
-
return LabelAndSwitchButton(
|
|
15
|
+
return LabelAndSwitchButton(task, key)
|
|
16
16
|
elif isinstance(value, list):
|
|
17
|
-
return ModifyListItem(
|
|
17
|
+
return ModifyListItem(task, key)
|
|
18
18
|
elif isinstance(value, int):
|
|
19
|
-
return LabelAndSpinBox(
|
|
19
|
+
return LabelAndSpinBox(task, key)
|
|
20
20
|
elif isinstance(value, float):
|
|
21
|
-
return LabelAndDoubleSpinBox(
|
|
21
|
+
return LabelAndDoubleSpinBox(task, key)
|
|
22
22
|
elif isinstance(value, str):
|
|
23
|
-
return LabelAndLineEdit(
|
|
23
|
+
return LabelAndLineEdit(task, key)
|
|
24
24
|
else:
|
|
25
25
|
raise ValueError(f"invalid type {type(value)}, value {value}")
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from ok.gui.tasks.LabelAndWidget import LabelAndWidget
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ConfigLabelAndWidget(LabelAndWidget):
|
|
5
|
+
|
|
6
|
+
def __init__(self, task, key: str):
|
|
7
|
+
desc = None
|
|
8
|
+
self.key = key
|
|
9
|
+
self.task = task
|
|
10
|
+
self.config = task.config
|
|
11
|
+
if task.config_description is not None:
|
|
12
|
+
desc = task.config_description.get(key)
|
|
13
|
+
super().__init__(key, desc)
|
|
14
|
+
|
|
15
|
+
def update_config(self, value):
|
|
16
|
+
self.config[self.key] = value
|
|
@@ -5,10 +5,9 @@ from ok.gui.tasks.ConfigLabelAndWidget import ConfigLabelAndWidget
|
|
|
5
5
|
|
|
6
6
|
class LabelAndDoubleSpinBox(ConfigLabelAndWidget):
|
|
7
7
|
|
|
8
|
-
def __init__(self,
|
|
9
|
-
super().__init__(
|
|
8
|
+
def __init__(self, task, key: str):
|
|
9
|
+
super().__init__(task, key)
|
|
10
10
|
self.key = key
|
|
11
|
-
self.config = config
|
|
12
11
|
self.spin_box = DoubleSpinBox()
|
|
13
12
|
self.update_value()
|
|
14
13
|
self.spin_box.valueChanged.connect(self.value_changed)
|
|
@@ -18,4 +17,4 @@ class LabelAndDoubleSpinBox(ConfigLabelAndWidget):
|
|
|
18
17
|
self.spin_box.setValue(self.config.get(self.key))
|
|
19
18
|
|
|
20
19
|
def value_changed(self, value):
|
|
21
|
-
self.
|
|
20
|
+
self.update_config(value)
|
|
@@ -5,10 +5,9 @@ from ok.gui.tasks.ConfigLabelAndWidget import ConfigLabelAndWidget
|
|
|
5
5
|
|
|
6
6
|
class LabelAndDropDown(ConfigLabelAndWidget):
|
|
7
7
|
|
|
8
|
-
def __init__(self,
|
|
9
|
-
super().__init__(
|
|
8
|
+
def __init__(self, task, options, key: str):
|
|
9
|
+
super().__init__(task, key)
|
|
10
10
|
self.key = key
|
|
11
|
-
self.config = config
|
|
12
11
|
self.combo_box = ComboBox()
|
|
13
12
|
self.combo_box.addItems(options)
|
|
14
13
|
self.combo_box.setCurrentIndex(find_string_index(options, self.config.get(self.key)))
|
|
@@ -17,7 +16,7 @@ class LabelAndDropDown(ConfigLabelAndWidget):
|
|
|
17
16
|
self.add_widget(self.combo_box)
|
|
18
17
|
|
|
19
18
|
def text_changed(self, text):
|
|
20
|
-
self.
|
|
19
|
+
self.update_config(text)
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
def find_string_index(my_list, target_string):
|
|
@@ -5,10 +5,9 @@ from ok.gui.tasks.ConfigLabelAndWidget import ConfigLabelAndWidget
|
|
|
5
5
|
|
|
6
6
|
class LabelAndLineEdit(ConfigLabelAndWidget):
|
|
7
7
|
|
|
8
|
-
def __init__(self,
|
|
9
|
-
super().__init__(
|
|
8
|
+
def __init__(self, task, key: str):
|
|
9
|
+
super().__init__(task, key)
|
|
10
10
|
self.key = key
|
|
11
|
-
self.config = config
|
|
12
11
|
self.line_edit = LineEdit()
|
|
13
12
|
self.update_value()
|
|
14
13
|
self.line_edit.textChanged.connect(self.value_changed)
|
|
@@ -18,4 +17,4 @@ class LabelAndLineEdit(ConfigLabelAndWidget):
|
|
|
18
17
|
self.line_edit.setText(self.config.get(self.key))
|
|
19
18
|
|
|
20
19
|
def value_changed(self, value):
|
|
21
|
-
self.
|
|
20
|
+
self.update_config(value)
|
|
@@ -5,10 +5,9 @@ from ok.gui.tasks.ConfigLabelAndWidget import ConfigLabelAndWidget
|
|
|
5
5
|
|
|
6
6
|
class LabelAndSpinBox(ConfigLabelAndWidget):
|
|
7
7
|
|
|
8
|
-
def __init__(self,
|
|
9
|
-
super().__init__(
|
|
8
|
+
def __init__(self, task, key: str):
|
|
9
|
+
super().__init__(task, key)
|
|
10
10
|
self.key = key
|
|
11
|
-
self.config = config
|
|
12
11
|
self.spin_box = SpinBox()
|
|
13
12
|
self.spin_box.setFixedWidth(130)
|
|
14
13
|
self.update_value()
|
|
@@ -19,4 +18,4 @@ class LabelAndSpinBox(ConfigLabelAndWidget):
|
|
|
19
18
|
self.spin_box.setValue(self.config.get(self.key))
|
|
20
19
|
|
|
21
20
|
def value_changed(self, value):
|
|
22
|
-
self.
|
|
21
|
+
self.update_config(value)
|
|
@@ -5,10 +5,9 @@ from ok.gui.tasks.ConfigLabelAndWidget import ConfigLabelAndWidget
|
|
|
5
5
|
|
|
6
6
|
class LabelAndSwitchButton(ConfigLabelAndWidget):
|
|
7
7
|
|
|
8
|
-
def __init__(self,
|
|
9
|
-
super().__init__(
|
|
8
|
+
def __init__(self, task, key: str):
|
|
9
|
+
super().__init__(task, key)
|
|
10
10
|
self.key = key
|
|
11
|
-
self.config = config
|
|
12
11
|
self.switch_button = SwitchButton()
|
|
13
12
|
self.switch_button.setOnText(self.tr('Yes'))
|
|
14
13
|
self.switch_button.setOffText(self.tr('No'))
|
|
@@ -20,4 +19,4 @@ class LabelAndSwitchButton(ConfigLabelAndWidget):
|
|
|
20
19
|
self.switch_button.setChecked(self.config.get(self.key))
|
|
21
20
|
|
|
22
21
|
def check_changed(self, checked):
|
|
23
|
-
self.
|
|
22
|
+
self.update_config(checked)
|
|
@@ -8,10 +8,8 @@ from ok.gui.widget.UpdateConfigWidgetItem import value_to_string
|
|
|
8
8
|
|
|
9
9
|
class ModifyListItem(ConfigLabelAndWidget):
|
|
10
10
|
|
|
11
|
-
def __init__(self,
|
|
12
|
-
super().__init__(
|
|
13
|
-
self.key = key
|
|
14
|
-
self.config = config
|
|
11
|
+
def __init__(self, task, key: str):
|
|
12
|
+
super().__init__(task, key)
|
|
15
13
|
self.switch_button = PushButton(self.tr('Modify'))
|
|
16
14
|
self.switch_button.clicked.connect(self.clicked)
|
|
17
15
|
self.list_text = QLabel("")
|
|
@@ -20,7 +18,15 @@ class ModifyListItem(ConfigLabelAndWidget):
|
|
|
20
18
|
self.add_widget(self.switch_button)
|
|
21
19
|
|
|
22
20
|
def update_value(self):
|
|
23
|
-
self.
|
|
21
|
+
items = self.config.get(self.key)
|
|
22
|
+
total_length = sum(len(item) for item in items)
|
|
23
|
+
|
|
24
|
+
if total_length > 30:
|
|
25
|
+
display_text = "\n".join(items)
|
|
26
|
+
else:
|
|
27
|
+
display_text = value_to_string(items)
|
|
28
|
+
|
|
29
|
+
self.list_text.setText(display_text)
|
|
24
30
|
|
|
25
31
|
def clicked(self):
|
|
26
32
|
dialog = ModifyListDialog(self.config.get(self.key), self.window())
|
|
@@ -28,5 +34,5 @@ class ModifyListItem(ConfigLabelAndWidget):
|
|
|
28
34
|
dialog.exec()
|
|
29
35
|
|
|
30
36
|
def list_modified(self, the_list):
|
|
31
|
-
self.
|
|
37
|
+
self.update_config(the_list)
|
|
32
38
|
self.update_value()
|
|
@@ -61,7 +61,7 @@ class TaskCard(ExpandSettingCard):
|
|
|
61
61
|
self.task.disable()
|
|
62
62
|
|
|
63
63
|
def __addConfig(self, key: str, value):
|
|
64
|
-
widget = config_widget(self.task
|
|
64
|
+
widget = config_widget(self.task, key, value)
|
|
65
65
|
self.config_widgets.append(widget)
|
|
66
66
|
self.viewLayout.addWidget(widget)
|
|
67
67
|
self._adjustViewSize()
|