1
1
#!/usr/bin/python3.9
2
2
# -*- coding: utf-8 -*-
3
- from typing import Callable , List , Optional
3
+ import traceback
4
+ from types import FunctionType , TracebackType
5
+ from typing import Callable , List , Optional , Type
4
6
5
7
from copy import copy
6
8
from PyQt6 import QtCore , QtGui , QtTest , QtWidgets
14
16
import signal
15
17
import time
16
18
17
- from menu_bar import about , VERSION , viewHelp , checkForUpdates
18
- from settings_file import auto_split_directory , open_update_checker
19
+ from menu_bar import about , VERSION , viewHelp , checkForUpdates , open_update_checker
20
+ from settings_file import auto_split_directory
19
21
from split_parser import BELOW_FLAG , DUMMY_FLAG , PAUSE_FLAG
20
22
import capture_windows
21
23
import compare
31
33
DISPLAY_RESIZE_WIDTH = 240
32
34
DISPLAY_RESIZE_HEIGHT = 180
33
35
DISPLAY_RESIZE = (DISPLAY_RESIZE_WIDTH , DISPLAY_RESIZE_HEIGHT )
34
-
36
+ CREATE_NEW_ISSUE_MESSAGE = \
37
+ "Please create a New Issue at <a href='https://github.com/Toufool/Auto-Split/issues'>"
38
+ "github.com/Toufool/Auto-Split/issues</a>, describe what happened, and copy & paste the error message below"
35
39
36
40
class AutoSplit (QtWidgets .QMainWindow , design .Ui_MainWindow ):
37
41
from hotkeys import send_command
@@ -53,6 +57,8 @@ class AutoSplit(QtWidgets.QMainWindow, design.Ui_MainWindow):
53
57
pauseSignal = QtCore .pyqtSignal ()
54
58
afterSettingHotkeySignal = QtCore .pyqtSignal ()
55
59
updateCheckerWidgetSignal = QtCore .pyqtSignal (str , bool )
60
+ # Use this signal when trying to show an error from outside the main thread
61
+ showErrorSignal = QtCore .pyqtSignal (FunctionType )
56
62
57
63
def __init__ (self , parent = None ):
58
64
super (AutoSplit , self ).__init__ (parent )
@@ -103,7 +109,7 @@ def run(self):
103
109
try :
104
110
line = input ()
105
111
except RuntimeError :
106
- # stdin not supported or lost, stop looking for inputs
112
+ self . autosplit . showErrorSignal . emit ( error_messages . stdinLostError )
107
113
break
108
114
# TODO: "AutoSplit Integration" needs to call this and wait instead of outright killing the app.
109
115
# TODO: See if we can also get LiveSplit to wait on Exit in "AutoSplit Integration"
@@ -173,6 +179,7 @@ def run(self):
173
179
self .resetSignal .connect (self .reset )
174
180
self .skipSplitSignal .connect (self .skipSplit )
175
181
self .undoSplitSignal .connect (self .undoSplit )
182
+ self .showErrorSignal .connect (lambda errorMessageBox : errorMessageBox ())
176
183
177
184
# live image checkbox
178
185
self .liveimageCheckBox .clicked .connect (self .checkLiveImage )
@@ -204,13 +211,6 @@ def run(self):
204
211
self .hwnd_title = ''
205
212
self .rect = ctypes .wintypes .RECT ()
206
213
207
- # Last loaded settings and last successful loaded settings file path to None until we try to load them
208
- self .last_loaded_settings = None
209
- self .last_successfully_loaded_settings_file_path = None
210
-
211
- if not self .is_auto_controlled :
212
- self .loadSettings (load_settings_on_open = True )
213
-
214
214
# Automatic timer start
215
215
self .timerStartImage = QtCore .QTimer ()
216
216
self .timerStartImage .timeout .connect (self .startImageFunction )
@@ -219,8 +219,12 @@ def run(self):
219
219
self .highest_similarity = 0.0
220
220
self .check_start_image_timestamp = 0.0
221
221
222
- # Try to load start image
223
- self .loadStartImage ()
222
+ # Last loaded settings and last successful loaded settings file path to None until we try to load them
223
+ self .last_loaded_settings = None
224
+ self .last_successfully_loaded_settings_file_path = None
225
+
226
+ if not self .is_auto_controlled :
227
+ self .loadSettings (load_settings_on_open = True )
224
228
225
229
# FUNCTIONS
226
230
@@ -237,6 +241,7 @@ def browse(self):
237
241
# set the split image folder line to the directory text
238
242
self .split_image_directory = new_split_image_directory
239
243
self .splitimagefolderLineEdit .setText (f"{ new_split_image_directory } /" )
244
+ self .loadStartImage ()
240
245
241
246
def checkLiveImage (self ):
242
247
if self .liveimageCheckBox .isChecked ():
@@ -296,6 +301,10 @@ def loadStartImage(self, started_by_button=False, wait_for_delay=True):
296
301
error_messages .noKeywordImageError ('start_auto_splitter' )
297
302
return
298
303
304
+ if self .start_image_name is not None and (not self .splitLineEdit .text () or not self .resetLineEdit .text () or not self .pausehotkeyLineEdit .text ()) and not self .is_auto_controlled :
305
+ error_messages .loadStartImageError ()
306
+ return
307
+
299
308
self .split_image_filenames = os .listdir (self .split_image_directory )
300
309
self .split_image_number = 0
301
310
self .start_image_mask = None
@@ -340,8 +349,7 @@ def loadStartImage(self, started_by_button=False, wait_for_delay=True):
340
349
QtWidgets .QApplication .processEvents ()
341
350
342
351
def startImageFunction (self ):
343
- if time .time () < self .check_start_image_timestamp \
344
- or (not self .splitLineEdit .text () and not self .is_auto_controlled ):
352
+ if time .time () < self .check_start_image_timestamp :
345
353
pause_time_left = "{:.1f}" .format (self .check_start_image_timestamp - time .time ())
346
354
self .currentSplitImage .setText (f'None\n (Paused before loading Start Image).\n { pause_time_left } sec remaining' )
347
355
return
@@ -751,6 +759,7 @@ def autoSplitter(self):
751
759
reset_similarity = self .compareImage (self .reset_image , self .reset_mask , capture )
752
760
if reset_similarity >= self .reset_image_threshold :
753
761
self .send_command ("reset" )
762
+ self .reset ()
754
763
755
764
if self .checkForReset ():
756
765
return
@@ -1189,22 +1198,46 @@ def exit():
1189
1198
1190
1199
def main ():
1191
1200
app = QtWidgets .QApplication (sys .argv )
1192
- app .setWindowIcon (QtGui .QIcon (':/resources/icon.ico' ))
1193
-
1194
- main_window = AutoSplit ()
1195
- main_window .show ()
1196
- if main_window .actionCheck_for_Updates_on_Open .isChecked ():
1197
- checkForUpdates (main_window , check_on_open = True )
1201
+ try :
1202
+ app .setWindowIcon (QtGui .QIcon (':/resources/icon.ico' ))
1203
+ main_window = AutoSplit ()
1204
+ main_window .show ()
1205
+ # Needs to be after main_window.show() to be shown over
1206
+ if main_window .actionCheck_for_Updates_on_Open .isChecked ():
1207
+ checkForUpdates (main_window , check_on_open = True )
1208
+
1209
+ # Kickoff the event loop every so often so we can handle KeyboardInterrupt (^C)
1210
+ timer = QtCore .QTimer ()
1211
+ timer .timeout .connect (lambda : None )
1212
+ timer .start (500 )
1213
+
1214
+ exit_code = app .exec ()
1215
+ except Exception as exception :
1216
+ # Print error to console if not running in executable
1217
+ if getattr (sys , 'frozen' , False ):
1218
+ error_messages .exceptionTraceback (
1219
+ f"AutoSplit encountered an unrecoverable exception and will now close. { CREATE_NEW_ISSUE_MESSAGE } " ,
1220
+ exception )
1221
+ else :
1222
+ traceback .print_exception (type (exception ), exception , exception .__traceback__ )
1223
+ sys .exit (1 )
1198
1224
1199
- # Kickoff the event loop every so often so we can handle KeyboardInterrupt (^C)
1200
- timer = QtCore .QTimer ()
1201
- timer .timeout .connect (lambda : None )
1202
- timer .start (500 )
1203
1225
# Catch Keyboard Interrupts for a clean close
1204
- signal .signal (signal .SIGINT , lambda _ , __ : sys .exit (app ))
1226
+ signal .signal (signal .SIGINT , lambda code , _ : sys .exit (code ))
1227
+
1228
+ sys .exit (exit_code )
1205
1229
1206
- sys .exit (app .exec ())
1230
+
1231
+ def excepthook (exceptionType : Type [BaseException ], exception : BaseException , traceback : Optional [TracebackType ]):
1232
+ # Catch Keyboard Interrupts for a clean close
1233
+ if exceptionType is KeyboardInterrupt :
1234
+ sys .exit (0 )
1235
+ error_messages .exceptionTraceback (
1236
+ "AutoSplit encountered an unhandled exception and will try to recover, "
1237
+ f"however, there is no guarantee everything will work properly. { CREATE_NEW_ISSUE_MESSAGE } " ,
1238
+ exception )
1207
1239
1208
1240
1209
1241
if __name__ == '__main__' :
1242
+ sys .excepthook = excepthook
1210
1243
main ()
0 commit comments