@@ -286,10 +286,13 @@ class CameraWidget(QWidget):
286
286
frame_processed = Signal (object ) # Processed frame with annotations
287
287
error_occurred = Signal (str ) # Error message
288
288
289
- def __init__ (self ):
289
+ def __init__ (self , main_window = None ):
290
290
super ().__init__ ()
291
291
self .setMinimumSize (640 , 480 )
292
292
293
+ # Reference to main window for directory tracking
294
+ self .main_window = main_window
295
+
293
296
# Camera variables
294
297
self .camera = None
295
298
self .current_camera_device = None
@@ -858,14 +861,25 @@ def capture_frame(self, save_to_file=True):
858
861
859
862
# Let user choose save location
860
863
from PySide6 .QtWidgets import QFileDialog
864
+ import os
865
+
866
+ # Get initial directory from main window if available
867
+ initial_dir = filename
868
+ if self .main_window and hasattr (self .main_window , 'get_last_used_directory' ):
869
+ initial_dir = os .path .join (self .main_window .get_last_used_directory (), filename )
870
+
861
871
file_path , _ = QFileDialog .getSaveFileName (
862
872
self ,
863
873
"Save Captured Frame" ,
864
- filename ,
874
+ initial_dir ,
865
875
"JPEG files (*.jpg);;PNG files (*.png);;BMP files (*.bmp);;All files (*.*)"
866
876
)
867
877
868
878
if file_path :
879
+ # Update directory tracking in main window
880
+ if self .main_window and hasattr (self .main_window , 'update_last_used_directory' ):
881
+ self .main_window .update_last_used_directory (file_path )
882
+
869
883
# Save the frame to file
870
884
import cv2
871
885
success = cv2 .imwrite (file_path , captured_frame )
@@ -1488,6 +1502,9 @@ def __init__(self):
1488
1502
self .current_page_index = 0
1489
1503
self .page_results = {} # Store detection results for each page
1490
1504
self .is_processing = False
1505
+
1506
+ # Directory tracking for file dialogs
1507
+ self .last_used_directory = "" # Track last used directory for file dialogs
1491
1508
self .process_start_time = None
1492
1509
self .current_detection_mode = "Barcode" # Default detection mode
1493
1510
@@ -1509,6 +1526,17 @@ def __init__(self):
1509
1526
# Initialize Dynamsoft
1510
1527
self .initialize_license ()
1511
1528
1529
+ def update_last_used_directory (self , file_path ):
1530
+ """Update the last used directory from a file path."""
1531
+ import os
1532
+ if file_path :
1533
+ self .last_used_directory = os .path .dirname (file_path )
1534
+
1535
+ def get_last_used_directory (self ):
1536
+ """Get the last used directory, or current directory if none."""
1537
+ import os
1538
+ return self .last_used_directory if self .last_used_directory else os .getcwd ()
1539
+
1512
1540
def setup_ui (self ):
1513
1541
"""Setup the main user interface with tabbed layout."""
1514
1542
central_widget = QWidget ()
@@ -1572,7 +1600,7 @@ def create_camera_mode_tab(self):
1572
1600
splitter .addWidget (self .camera_control_panel )
1573
1601
1574
1602
# Camera display (center)
1575
- self .camera_widget = CameraWidget ()
1603
+ self .camera_widget = CameraWidget (self )
1576
1604
1577
1605
# Set initial detection mode from combo box
1578
1606
initial_mode = list (DETECTION_MODES .keys ())[0 ] # Default to first mode (Barcode)
@@ -2273,11 +2301,12 @@ def export_camera_results(self):
2273
2301
file_path , _ = QFileDialog .getSaveFileName (
2274
2302
self ,
2275
2303
"Export Camera Results" ,
2276
- f"camera_detections{ ext } " ,
2304
+ os . path . join ( self . get_last_used_directory (), f"camera_detections{ ext } " ) ,
2277
2305
f"{ format_name } files (*{ ext } );;All files (*.*)"
2278
2306
)
2279
2307
2280
2308
if file_path :
2309
+ self .update_last_used_directory (file_path )
2281
2310
if ext == ".txt" :
2282
2311
self .export_camera_to_text (file_path )
2283
2312
elif ext == ".csv" :
@@ -2515,11 +2544,12 @@ def load_file(self):
2515
2544
file_path , _ = QFileDialog .getOpenFileName (
2516
2545
self ,
2517
2546
"Select Image or PDF file" ,
2518
- "" ,
2547
+ self . get_last_used_directory () ,
2519
2548
file_types
2520
2549
)
2521
2550
2522
2551
if file_path :
2552
+ self .update_last_used_directory (file_path )
2523
2553
self .load_file_path (file_path )
2524
2554
2525
2555
def load_file_path (self , file_path ):
@@ -2948,11 +2978,12 @@ def save_normalized_document(self):
2948
2978
file_path , _ = QFileDialog .getSaveFileName (
2949
2979
self ,
2950
2980
"Save Normalized Document" ,
2951
- default_name ,
2981
+ os . path . join ( self . get_last_used_directory (), default_name ) ,
2952
2982
"JPEG files (*.jpg);;PNG files (*.png);;BMP files (*.bmp);;TIFF files (*.tiff);;All files (*.*)"
2953
2983
)
2954
2984
2955
2985
if file_path :
2986
+ self .update_last_used_directory (file_path )
2956
2987
# Save the image
2957
2988
success = cv2 .imwrite (file_path , normalized_image )
2958
2989
if success :
@@ -3028,13 +3059,14 @@ def save_face_crops(self):
3028
3059
directory = QFileDialog .getExistingDirectory (
3029
3060
self ,
3030
3061
"Select Directory to Save Face Crops" ,
3031
- "" ,
3062
+ self . get_last_used_directory () ,
3032
3063
QFileDialog .Option .ShowDirsOnly
3033
3064
)
3034
3065
3035
3066
if not directory :
3036
3067
return
3037
3068
3069
+ self .update_last_used_directory (directory )
3038
3070
saved_count = 0
3039
3071
3040
3072
# Generate base filename
@@ -3372,11 +3404,12 @@ def export_results(self):
3372
3404
file_path , _ = QFileDialog .getSaveFileName (
3373
3405
self ,
3374
3406
"Export Results" ,
3375
- f"barcode_results{ ext } " ,
3407
+ os . path . join ( self . get_last_used_directory (), f"barcode_results{ ext } " ) ,
3376
3408
f"{ format_name } files (*{ ext } );;All files (*.*)"
3377
3409
)
3378
3410
3379
3411
if file_path :
3412
+ self .update_last_used_directory (file_path )
3380
3413
try :
3381
3414
if ext == ".txt" :
3382
3415
self .export_to_text (file_path )
@@ -3606,48 +3639,39 @@ def enter_license_key(self):
3606
3639
3607
3640
if reply == QMessageBox .StandardButton .Yes :
3608
3641
try :
3609
- # Test the new license
3610
- test_error_code , test_error_message = LicenseManager . init_license ( license_key )
3642
+ # Update the global LICENSE_KEY
3643
+ LICENSE_KEY = license_key
3611
3644
3612
- if test_error_code == EnumErrorCode .EC_OK or test_error_code == EnumErrorCode .EC_LICENSE_CACHE_USED :
3613
- # License is valid, update the global LICENSE_KEY
3614
- LICENSE_KEY = license_key
3645
+ # Reinitialize the license system
3646
+ _LICENSE_INITIALIZED = False
3647
+
3648
+ # Test and initialize with the new license
3649
+ if initialize_license_once ():
3650
+ # Reinitialize the CVR instance
3651
+ if self .cvr_instance :
3652
+ self .cvr_instance = None
3615
3653
3616
- # Reinitialize the license system
3617
- _LICENSE_INITIALIZED = False
3654
+ self .cvr_instance = CaptureVisionRouter ()
3655
+ intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
3656
+ self .custom_receiver = MyIntermediateResultReceiver (intermediate_result_manager )
3657
+ intermediate_result_manager .add_result_receiver (self .custom_receiver )
3618
3658
3619
- if initialize_license_once ():
3620
- # Reinitialize the CVR instance
3621
- if self .cvr_instance :
3622
- self .cvr_instance = None
3623
-
3624
- self .cvr_instance = CaptureVisionRouter ()
3625
- intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
3626
- self .custom_receiver = MyIntermediateResultReceiver (intermediate_result_manager )
3627
- intermediate_result_manager .add_result_receiver (self .custom_receiver )
3628
-
3629
- # Update camera widget if it exists
3630
- if hasattr (self , 'camera_widget' ):
3631
- self .camera_widget .initialize_dynamsoft_camera (self .cvr_instance )
3659
+ # Update camera widget if it exists
3660
+ if hasattr (self , 'camera_widget' ):
3661
+ self .camera_widget .initialize_dynamsoft_camera (self .cvr_instance )
3632
3662
3633
- QMessageBox .information (
3634
- self ,
3635
- "License Updated" ,
3636
- "✅ License key updated successfully!\n \n The new license is now active."
3637
- )
3638
-
3639
- self .log_message ("✅ License key updated successfully" )
3640
- else :
3641
- QMessageBox .critical (
3642
- self ,
3643
- "License Error" ,
3644
- "❌ Failed to reinitialize with new license key.\n \n Please restart the application."
3645
- )
3663
+ QMessageBox .information (
3664
+ self ,
3665
+ "License Updated" ,
3666
+ "✅ License key updated successfully!\n \n The new license is now active."
3667
+ )
3668
+
3669
+ self .log_message ("✅ License key updated successfully" )
3646
3670
else :
3647
3671
QMessageBox .critical (
3648
3672
self ,
3649
- "Invalid License" ,
3650
- f "❌ License validation failed: \n \n Error Code: { test_error_code } \n Error Message: { test_error_message } \n \n Please check your license key and try again."
3673
+ "License Error " ,
3674
+ "❌ Failed to initialize with new license key. \n \n Please check your license key and try again."
3651
3675
)
3652
3676
3653
3677
except Exception as e :
@@ -3659,11 +3683,6 @@ def enter_license_key(self):
3659
3683
3660
3684
def main ():
3661
3685
"""Main application entry point."""
3662
- # Initialize license ONCE at startup before creating any UI
3663
- print ("🔑 Initializing Dynamsoft license..." )
3664
- if not initialize_license_once ():
3665
- print ("❌ Failed to initialize license. Exiting." )
3666
- sys .exit (1 )
3667
3686
3668
3687
app = QApplication (sys .argv )
3669
3688
0 commit comments