-
-
Notifications
You must be signed in to change notification settings - Fork 0
06 configuration
Zuko edited this page Jan 21, 2026
·
1 revision
Singleton configuration manager với JSON persistence và nested key access
Config quản lý application configuration:
- Singleton pattern (one instance per application)
- JSON file persistence (
data/config/config.json) - Nested key access với dot notation
- Thread-safe operations (QMutex)
- Auto-create default config
from core import Config
config = Config() # Always returns same instance
# Or via QtAppContext
from core import QtAppContext
config = QtAppContext.globalInstance().configvalue = config.get('key.nested.path', default=None)config.set('key.nested.path', value)config.save()config.load() # Auto-called on first accessfrom core import Config
config = Config()
# Get values
appName = config.get('app.name')
theme = config.get('ui.theme', default='auto')
# Set values
config.set('ui.theme', 'dark')
config.set('app.debug', True)
# Save to disk
config.save()config = Config()
# Set nested values
config.set('database.host', 'localhost')
config.set('database.port', 5432)
config.set('database.credentials.username', 'admin')
# Get nested values
host = config.get('database.host')
username = config.get('database.credentials.username')# Default config created automatically if file doesn't exist
{
"app": {
"name": "Base Qt Application",
"version": "1.0.0",
"debug": false
},
"ui": {
"theme": "auto",
"language": "en",
"high_dpi": true
},
"logging": {
"level": "INFO",
"file": "app.log"
},
"consolelog": {
"enable": true,
"level": "DEBUG"
}
}from core import Config
class AppSettings:
def __init__(self):
self.config = Config()
def getTheme(self):
return self.config.get('ui.theme', default='auto')
def setTheme(self, theme):
self.config.set('ui.theme', theme)
self.config.save()
def isDebugMode(self):
return self.config.get('app.debug', default=False)# WidgetManager automatically uses Config for persistence
from core import BaseCtlHandler
class SettingsHandler(BaseCtlHandler):
def onSaveSettings(self):
# Saves to config automatically
self.widgetManager.set('theme', 'dark', saveToConfig=True)
# Config key: "SettingsController.theme"Path: {PROJECT_ROOT}/data/config/config.json
Auto-created: If file doesn't exist, default config is created
Format: JSON with indentation (4 spaces)
# Use descriptive nested keys
config.set('database.connection.timeout', 30)
config.set('api.endpoints.users', '/api/v1/users')
# Provide defaults
theme = config.get('ui.theme', default='auto')
# Save after important changes
config.set('user.preferences.language', 'vi')
config.save()
# Use constants for keys
class ConfigKeys:
APP_NAME = 'app.name'
UI_THEME = 'ui.theme'
theme = config.get(ConfigKeys.UI_THEME)# Don't use flat keys
config.set('database_host', 'localhost') # Use 'database.host'
# Don't forget to save
config.set('important.setting', value)
# Missing: config.save()
# Don't catch ConfigError silently
try:
config.load()
except:
pass # Wrong! Handle properly
# Don't modify config file manually while app running
# Use config.set() and config.save() instead- ✅
get(): Thread-safe (QMutex) - ✅
set(): Thread-safe (QMutex) - ✅
save(): Thread-safe (QMutex) - ✅
load(): Thread-safe (QMutex)
from core import Config
class AppConfig:
def __init__(self):
self.config = Config()
@property
def appName(self):
return self.config.get('app.name', default='My App')
@property
def version(self):
return self.config.get('app.version', default='1.0.0')
@property
def isDebug(self):
return self.config.get('app.debug', default=False)
def setDebug(self, enabled):
self.config.set('app.debug', enabled)
self.config.save()class UserPreferences:
def __init__(self):
self.config = Config()
def getPreference(self, key, default=None):
return self.config.get(f'user.preferences.{key}', default=default)
def setPreference(self, key, value):
self.config.set(f'user.preferences.{key}', value)
self.config.save()
# Usage
prefs = UserPreferences()
prefs.setPreference('theme', 'dark')
prefs.setPreference('language', 'vi')
theme = prefs.getPreference('theme', default='auto')class FeatureFlags:
def __init__(self):
self.config = Config()
def isEnabled(self, feature):
return self.config.get(f'features.{feature}.enabled', default=False)
def enable(self, feature):
self.config.set(f'features.{feature}.enabled', True)
self.config.save()
def disable(self, feature):
self.config.set(f'features.{feature}.enabled', False)
self.config.save()
# Usage
flags = FeatureFlags()
if flags.isEnabled('experimental_ui'):
# Use experimental UI
pass- QtAppContext - Config access
- WidgetManager - Widget persistence
- PathHelper - Path management
Q: Config file not found
# Auto-created with defaults
config = Config()
config.load() # Creates default config if missingQ: Nested key not working
# Ensure parent keys exist
config.set('a.b.c', value) # Auto-creates a.b if missing
# Get with default
value = config.get('a.b.c', default=None)Q: Changes not persisted
# Must call save()
config.set('key', 'value')
config.save() # Don't forget!