Refactor settings class
This commit is contained in:
parent
3c63864997
commit
c64a5eae9b
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,3 +16,4 @@ cscope*
|
|||||||
.ycm_extra_conf.py
|
.ycm_extra_conf.py
|
||||||
.subvimrc
|
.subvimrc
|
||||||
.vscode
|
.vscode
|
||||||
|
*.pkl
|
||||||
|
|||||||
3
Makefile
3
Makefile
@ -23,4 +23,7 @@ qt4py3:
|
|||||||
qt5py3:
|
qt5py3:
|
||||||
pyrcc5 -o resources.py resources.qrc
|
pyrcc5 -o resources.py resources.qrc
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f .settings.pkl resources.pyc
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|||||||
101
labelImg.py
101
labelImg.py
@ -28,6 +28,7 @@ import resources
|
|||||||
# Add internal libs
|
# Add internal libs
|
||||||
from libs.constants import *
|
from libs.constants import *
|
||||||
from libs.lib import struct, newAction, newIcon, addActions, fmtShortcut
|
from libs.lib import struct, newAction, newIcon, addActions, fmtShortcut
|
||||||
|
from libs.settings import Settings
|
||||||
from libs.shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR
|
from libs.shape import Shape, DEFAULT_LINE_COLOR, DEFAULT_FILL_COLOR
|
||||||
from libs.canvas import Canvas
|
from libs.canvas import Canvas
|
||||||
from libs.zoomWidget import ZoomWidget
|
from libs.zoomWidget import ZoomWidget
|
||||||
@ -397,40 +398,10 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
|
|
||||||
# Load predefined classes to the list
|
# Load predefined classes to the list
|
||||||
self.loadPredefinedClasses(defaultPrefdefClassFile)
|
self.loadPredefinedClasses(defaultPrefdefClassFile)
|
||||||
# XXX: Could be completely declarative.
|
|
||||||
# Restore application settings.
|
|
||||||
if have_qstring():
|
|
||||||
types = {
|
|
||||||
SETTING_FILENAME: QString,
|
|
||||||
SETTING_RECENT_FILES: QStringList,
|
|
||||||
SETTING_WIN_SIZE: QSize,
|
|
||||||
SETTING_WIN_POSE: QPoint,
|
|
||||||
SETTING_WIN_GEOMETRY: QByteArray,
|
|
||||||
SETTING_LINE_COLOR: QColor,
|
|
||||||
SETTING_FILL_COLOR: QColor,
|
|
||||||
SETTING_ADVANCE_MODE: bool,
|
|
||||||
# Docks and toolbars:
|
|
||||||
SETTING_WIN_STATE: QByteArray,
|
|
||||||
SETTING_SAVE_DIR: QString,
|
|
||||||
SETTING_LAST_OPEN_DIR: QString,
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
types = {
|
|
||||||
SETTING_FILENAME: str,
|
|
||||||
SETTING_RECENT_FILES: list,
|
|
||||||
SETTING_WIN_SIZE: QSize,
|
|
||||||
SETTING_WIN_POSE: QPoint,
|
|
||||||
SETTING_WIN_GEOMETRY: QByteArray,
|
|
||||||
SETTING_LINE_COLOR: QColor,
|
|
||||||
SETTING_FILL_COLOR: QColor,
|
|
||||||
SETTING_ADVANCE_MODE: bool,
|
|
||||||
# Docks and toolbars:
|
|
||||||
SETTING_WIN_STATE: QByteArray,
|
|
||||||
SETTING_SAVE_DIR: str,
|
|
||||||
SETTING_LAST_OPEN_DIR: str,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.settings = settings = Settings(types)
|
self.settings = Settings()
|
||||||
|
self.settings.load()
|
||||||
|
settings = self.settings
|
||||||
|
|
||||||
## Fix the compatible issue for qt4 and qt5. Convert the QStringList to python list
|
## Fix the compatible issue for qt4 and qt5. Convert the QStringList to python list
|
||||||
if settings.get(SETTING_RECENT_FILES):
|
if settings.get(SETTING_RECENT_FILES):
|
||||||
@ -1005,30 +976,31 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
if not self.mayContinue():
|
if not self.mayContinue():
|
||||||
event.ignore()
|
event.ignore()
|
||||||
s = self.settings
|
settings = self.settings
|
||||||
# If it loads images from dir, don't load it at the begining
|
# If it loads images from dir, don't load it at the begining
|
||||||
if self.dirname is None:
|
if self.dirname is None:
|
||||||
s[SETTING_FILENAME] = self.filePath if self.filePath else ''
|
settings[SETTING_FILENAME] = self.filePath if self.filePath else ''
|
||||||
else:
|
else:
|
||||||
s[SETTING_FILENAME] = ''
|
settings[SETTING_FILENAME] = ''
|
||||||
|
|
||||||
s[SETTING_WIN_SIZE] = self.size()
|
settings[SETTING_WIN_SIZE] = self.size()
|
||||||
s[SETTING_WIN_POSE] = self.pos()
|
settings[SETTING_WIN_POSE] = self.pos()
|
||||||
s[SETTING_WIN_STATE] = self.saveState()
|
settings[SETTING_WIN_STATE] = self.saveState()
|
||||||
s[SETTING_LINE_COLOR] = self.lineColor
|
settings[SETTING_LINE_COLOR] = self.lineColor
|
||||||
s[SETTING_FILL_COLOR] = self.fillColor
|
settings[SETTING_FILL_COLOR] = self.fillColor
|
||||||
s[SETTING_RECENT_FILES] = self.recentFiles
|
settings[SETTING_RECENT_FILES] = self.recentFiles
|
||||||
s[SETTING_ADVANCE_MODE] = not self._beginner
|
settings[SETTING_ADVANCE_MODE] = not self._beginner
|
||||||
if self.defaultSaveDir is not None and len(self.defaultSaveDir) > 1:
|
if self.defaultSaveDir is not None and len(self.defaultSaveDir) > 1:
|
||||||
s[SETTING_SAVE_DIR] = ustr(self.defaultSaveDir)
|
settings[SETTING_SAVE_DIR] = ustr(self.defaultSaveDir)
|
||||||
else:
|
else:
|
||||||
s[SETTING_SAVE_DIR] = ""
|
settings[SETTING_SAVE_DIR] = ""
|
||||||
|
|
||||||
if self.lastOpenDir is not None and len(self.lastOpenDir) > 1:
|
if self.lastOpenDir is not None and len(self.lastOpenDir) > 1:
|
||||||
s[SETTING_LAST_OPEN_DIR] = self.lastOpenDir
|
settings[SETTING_LAST_OPEN_DIR] = self.lastOpenDir
|
||||||
else:
|
else:
|
||||||
s[SETTING_LAST_OPEN_DIR] = ""
|
settings[SETTING_LAST_OPEN_DIR] = ""
|
||||||
|
|
||||||
|
settings.save()
|
||||||
## User Dialogs ##
|
## User Dialogs ##
|
||||||
|
|
||||||
def loadRecent(self, filename):
|
def loadRecent(self, filename):
|
||||||
@ -1314,41 +1286,6 @@ class MainWindow(QMainWindow, WindowMixin):
|
|||||||
self.canvas.verified = tVocParseReader.verified
|
self.canvas.verified = tVocParseReader.verified
|
||||||
|
|
||||||
|
|
||||||
class Settings(object):
|
|
||||||
"""Convenience dict-like wrapper around QSettings."""
|
|
||||||
|
|
||||||
def __init__(self, types=None):
|
|
||||||
self.data = QSettings()
|
|
||||||
self.types = defaultdict(lambda: QVariant, types if types else {})
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
t = self.types[key]
|
|
||||||
self.data.setValue(key,
|
|
||||||
t(value) if not isinstance(value, t) else value)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return self._cast(key, self.data.value(key))
|
|
||||||
|
|
||||||
def get(self, key, default=None):
|
|
||||||
return self._cast(key, self.data.value(key, default))
|
|
||||||
|
|
||||||
def _cast(self, key, value):
|
|
||||||
# XXX: Very nasty way of converting types to QVariant methods :P
|
|
||||||
t = self.types.get(key)
|
|
||||||
if t is not None and t != QVariant:
|
|
||||||
if t is str:
|
|
||||||
return ustr(value)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
method = getattr(QVariant, re.sub(
|
|
||||||
'^Q', 'to', t.__name__, count=1))
|
|
||||||
return method(value)
|
|
||||||
except AttributeError as e:
|
|
||||||
# print(e)
|
|
||||||
return value
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def inverted(color):
|
def inverted(color):
|
||||||
return QColor(*[255 - v for v in color.getRgb()])
|
return QColor(*[255 - v for v in color.getRgb()])
|
||||||
|
|
||||||
|
|||||||
32
libs/settings.py
Normal file
32
libs/settings.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import pickle
|
||||||
|
import os
|
||||||
|
|
||||||
|
class Settings(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.data = {}
|
||||||
|
self.path = '.settings.pkl'
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.data[key] = value
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.data[key]
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
if key in self.data:
|
||||||
|
return self.data[key]
|
||||||
|
return default
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
with open(self.path, 'wb') as f:
|
||||||
|
pickle.dump(self.data, f, pickle.HIGHEST_PROTOCOL)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
if os.path.exists(self.path):
|
||||||
|
with open(self.path, 'rb') as f:
|
||||||
|
self.data = pickle.load(f)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
25
tests/test_settings.py
Normal file
25
tests/test_settings.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from unittest import TestCase
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
__author__ = 'TzuTaLin'
|
||||||
|
|
||||||
|
dir_name = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
libs_path = os.path.join(dir_name, '..', 'libs')
|
||||||
|
sys.path.insert(0, libs_path)
|
||||||
|
from settings import Settings
|
||||||
|
|
||||||
|
class TestSettings(TestCase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
wSetting = Settings()
|
||||||
|
wSetting['test0'] = 'hello'
|
||||||
|
wSetting['test1'] = 10
|
||||||
|
wSetting['test2'] = [0, 2, 3]
|
||||||
|
self.assertEqual(wSetting.get('test3', 3), 3)
|
||||||
|
self.assertEqual(wSetting.save(), True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Loading…
x
Reference in New Issue
Block a user