@@ -286,10 +286,13 @@ class CameraWidget(QWidget):
286286 frame_processed = Signal (object ) # Processed frame with annotations
287287 error_occurred = Signal (str ) # Error message
288288
289- def __init__ (self ):
289+ def __init__ (self , main_window = None ):
290290 super ().__init__ ()
291291 self .setMinimumSize (640 , 480 )
292292
293+ # Reference to main window for directory tracking
294+ self .main_window = main_window
295+
293296 # Camera variables
294297 self .camera = None
295298 self .current_camera_device = None
@@ -858,14 +861,25 @@ def capture_frame(self, save_to_file=True):
858861
859862 # Let user choose save location
860863 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+
861871 file_path , _ = QFileDialog .getSaveFileName (
862872 self ,
863873 "Save Captured Frame" ,
864- filename ,
874+ initial_dir ,
865875 "JPEG files (*.jpg);;PNG files (*.png);;BMP files (*.bmp);;All files (*.*)"
866876 )
867877
868878 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+
869883 # Save the frame to file
870884 import cv2
871885 success = cv2 .imwrite (file_path , captured_frame )
@@ -1488,6 +1502,9 @@ def __init__(self):
14881502 self .current_page_index = 0
14891503 self .page_results = {} # Store detection results for each page
14901504 self .is_processing = False
1505+
1506+ # Directory tracking for file dialogs
1507+ self .last_used_directory = "" # Track last used directory for file dialogs
14911508 self .process_start_time = None
14921509 self .current_detection_mode = "Barcode" # Default detection mode
14931510
@@ -1509,6 +1526,17 @@ def __init__(self):
15091526 # Initialize Dynamsoft
15101527 self .initialize_license ()
15111528
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+
15121540 def setup_ui (self ):
15131541 """Setup the main user interface with tabbed layout."""
15141542 central_widget = QWidget ()
@@ -1572,7 +1600,7 @@ def create_camera_mode_tab(self):
15721600 splitter .addWidget (self .camera_control_panel )
15731601
15741602 # Camera display (center)
1575- self .camera_widget = CameraWidget ()
1603+ self .camera_widget = CameraWidget (self )
15761604
15771605 # Set initial detection mode from combo box
15781606 initial_mode = list (DETECTION_MODES .keys ())[0 ] # Default to first mode (Barcode)
@@ -2273,11 +2301,12 @@ def export_camera_results(self):
22732301 file_path , _ = QFileDialog .getSaveFileName (
22742302 self ,
22752303 "Export Camera Results" ,
2276- f"camera_detections{ ext } " ,
2304+ os . path . join ( self . get_last_used_directory (), f"camera_detections{ ext } " ) ,
22772305 f"{ format_name } files (*{ ext } );;All files (*.*)"
22782306 )
22792307
22802308 if file_path :
2309+ self .update_last_used_directory (file_path )
22812310 if ext == ".txt" :
22822311 self .export_camera_to_text (file_path )
22832312 elif ext == ".csv" :
@@ -2515,11 +2544,12 @@ def load_file(self):
25152544 file_path , _ = QFileDialog .getOpenFileName (
25162545 self ,
25172546 "Select Image or PDF file" ,
2518- "" ,
2547+ self . get_last_used_directory () ,
25192548 file_types
25202549 )
25212550
25222551 if file_path :
2552+ self .update_last_used_directory (file_path )
25232553 self .load_file_path (file_path )
25242554
25252555 def load_file_path (self , file_path ):
@@ -2948,11 +2978,12 @@ def save_normalized_document(self):
29482978 file_path , _ = QFileDialog .getSaveFileName (
29492979 self ,
29502980 "Save Normalized Document" ,
2951- default_name ,
2981+ os . path . join ( self . get_last_used_directory (), default_name ) ,
29522982 "JPEG files (*.jpg);;PNG files (*.png);;BMP files (*.bmp);;TIFF files (*.tiff);;All files (*.*)"
29532983 )
29542984
29552985 if file_path :
2986+ self .update_last_used_directory (file_path )
29562987 # Save the image
29572988 success = cv2 .imwrite (file_path , normalized_image )
29582989 if success :
@@ -3028,13 +3059,14 @@ def save_face_crops(self):
30283059 directory = QFileDialog .getExistingDirectory (
30293060 self ,
30303061 "Select Directory to Save Face Crops" ,
3031- "" ,
3062+ self . get_last_used_directory () ,
30323063 QFileDialog .Option .ShowDirsOnly
30333064 )
30343065
30353066 if not directory :
30363067 return
30373068
3069+ self .update_last_used_directory (directory )
30383070 saved_count = 0
30393071
30403072 # Generate base filename
@@ -3372,11 +3404,12 @@ def export_results(self):
33723404 file_path , _ = QFileDialog .getSaveFileName (
33733405 self ,
33743406 "Export Results" ,
3375- f"barcode_results{ ext } " ,
3407+ os . path . join ( self . get_last_used_directory (), f"barcode_results{ ext } " ) ,
33763408 f"{ format_name } files (*{ ext } );;All files (*.*)"
33773409 )
33783410
33793411 if file_path :
3412+ self .update_last_used_directory (file_path )
33803413 try :
33813414 if ext == ".txt" :
33823415 self .export_to_text (file_path )
@@ -3606,48 +3639,39 @@ def enter_license_key(self):
36063639
36073640 if reply == QMessageBox .StandardButton .Yes :
36083641 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
36113644
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
36153653
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 )
36183658
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 )
36323662
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" )
36463670 else :
36473671 QMessageBox .critical (
36483672 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."
36513675 )
36523676
36533677 except Exception as e :
@@ -3659,11 +3683,6 @@ def enter_license_key(self):
36593683
36603684def main ():
36613685 """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 )
36673686
36683687 app = QApplication (sys .argv )
36693688
0 commit comments