Source code for labscript_utils.settings

#####################################################################
#                                                                   #
# settings.py                                                       #
#                                                                   #
# Copyright 2013, Monash University                                 #
#                                                                   #
# This file is part of the labscript suite (see                     #
# http://labscriptsuite.org) and is licensed under the Simplified   #
# BSD License. See the license.txt file in the root of the project  #
# for the full license.                                             #
#                                                                   #
#####################################################################
from qtutils.qt.QtCore import *
from qtutils.qt.QtGui import *
from qtutils.qt.QtWidgets import *

import labscript_utils.h5_lock, h5py
from labscript_utils.qtwidgets.fingertab import FingerTabWidget

# Create a generic interface for displaying pages of settings
[docs]class Settings(object):
[docs] def __init__(self,storage='hdf5',file=None,parent = None,page_classes = []): self.pages = {} self.instantiated_pages = {} self.dialog_open = False self.parent = parent self.storage = storage self.file = file self.callback_list = [] if not self.file: raise Exception('You must specify a file to load/save preferences from') for c in page_classes: self.add_settings_interface(c)
# This function can be called to add a interface # Each one of these will display as a seperate page in the settings window # You can not add a class more than once! # Classes must have unique Class.name attributes! (This might change later...)
[docs] def add_settings_interface(self,setting_class): if setting_class.name in self.pages: return False self.pages[setting_class.name] = setting_class(self.load(setting_class.name)) return True
[docs] def load(self,name): if self.storage == 'hdf5': with h5py.File(self.file,'r+') as h5file: # does the settings group exist? if 'preferences' not in h5file: h5file['/'].create_group('preferences') # is there an entry for this preference type? group = h5file['/preferences'] if name not in group.attrs: group.attrs[name] = repr({}) try: data = eval(group.attrs[name]) except Exception: # TODO: log this properly print('Could not load settings data for %s. It may contain data that could not be evaluated. All settings have now been lost'%name) data = {} return data else: raise Exception("the Settings module cannot handle the storage type: %s"%str(self.storage))
# A simple interface for accessing values in the settings interface
[docs] def get_value(self,settings_class,value_name): return self.pages[settings_class.name].get_value(value_name)
# goto_page should be the CLASS which you wish to go to!
[docs] def create_dialog(self,goto_page=None): if not self.dialog_open: self.instantiated_pages = {} # Create the dialog self.dialog = QDialog(self.parent) self.dialog.setModal(True) self.dialog.accepted.connect(self.on_save) self.dialog.rejected.connect(self.on_cancel) self.dialog.setMinimumSize(800,600) self.dialog.setWindowTitle("Preferences") # Remove the help flag next to the [X] close button self.dialog.setWindowFlags(self.dialog.windowFlags() & ~Qt.WindowContextHelpButtonHint) # Create the layout layout = QVBoxLayout(self.dialog) #Create the Notebook self.notebook = FingerTabWidget(self.dialog) self.notebook.setTabPosition(QTabWidget.West) self.notebook.show() layout.addWidget(self.notebook) # Create the button box widget = QWidget() hlayout = QHBoxLayout(widget) button_box = QDialogButtonBox() button_box.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.dialog.accept) button_box.rejected.connect(self.dialog.reject) hlayout.addItem(QSpacerItem(0,0,QSizePolicy.MinimumExpanding,QSizePolicy.Minimum)) hlayout.addWidget(button_box) layout.addWidget(widget) #sorted(a.items(),key=lambda x: x[1]) set_page = None #self.temp_pages = [] for name, c in sorted(self.pages.items()): page,icon = c.create_dialog(self.notebook) # save page self.instantiated_pages[c.__class__] = page # Create label #if isinstance(icon,gtk.Image): # use their icon # pass #else: # use default icon # pass self.notebook.addTab(page,c.name) if goto_page and isinstance(c,goto_page): # this is the page we want to go to! set_page = page # We do this here in case one of the settings pages specifically inserts itself in an out of order place (eg first) # We hope that everything will be in alphabetical order, but maybe not! if set_page: self.notebook.tabBar().setCurrentIndex(self.notebook.indexOf(set_page)) pass self.dialog.show() self.dialog_open = True else: if goto_page and goto_page in self.instantiated_pages: self.notebook.tabBar().setCurrentIndex(self.notebook.indexOf(self.instantiated_pages[goto_page]))
[docs] def register_callback(self,callback): self.callback_list.append(callback)
[docs] def remove_callback(self,callback): self.callback_list.remove(callback)
[docs] def on_save(self,*args,**kwargs): # Save the settings if self.storage == 'hdf5': with h5py.File(self.file,'r+') as h5file: group = h5file['/preferences'] for page in self.pages.values(): group.attrs[page.__class__.name] = repr(page.save()) else: # this should never happen as the exception will have been raised on load! pass # run callback functions! # Notifies other areas of the program that settings have changed for callback in self.callback_list: callback() self.close()
[docs] def on_cancel(self,*args,**kwargs): self.close()
[docs] def close(self,*args,**kwargs): if self.dialog_open: # Close the setting classes for page in self.pages.values(): page.close() self.dialog_open = False self.dialog.deleteLater() self.dialog = None