Source code for blacs.plugins.theme

#####################################################################
#                                                                   #
# /plugins/theme/__init__.py                                        #
#                                                                   #
# Copyright 2013, Monash University                                 #
#                                                                   #
# This file is part of the program BLACS, in 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.                                 #
#                                                                   #
#####################################################################
import logging
import os

from qtutils import *

from blacs.plugins import PLUGINS_DIR

name = "GUI Theme"
module = "theme" # should be folder name
logger = logging.getLogger('BLACS.plugin.%s'%module)


DEFAULT_STYLESHEET = """DigitalOutput {
    font-size: 12px;
    background-color: rgb(50,100,50,255);
    border: 1px solid rgb(50,100,50,128);
    border-radius: 3px;
    padding: 2px;
    color: #202020;
}

DigitalOutput:hover {
    background-color: rgb(50,130,50);
    border: None;
}

DigitalOutput:disabled{
   background-color: rgb(50,100,50,128);
   color: #505050;
}

DigitalOutput:checked {
    background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                      stop: 0 rgb(32,200,32), stop: 1 rgb(32,255,32));
    border: 1px solid #8f8f91;
    color: #000000;
}

DigitalOutput:hover:checked {
    background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                      stop: 0 rgb(32,200,32), stop: 1 rgb(120,255,120));
    border: 1px solid #8f8f91;
}

DigitalOutput:checked:disabled{
   background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                      stop: 0 rgba(32,200,32,128), stop: 1 rgba(32,255,32,128));
   color: #606060;
}

InvertedDigitalOutput {
    font-size: 12px;
    background-color: rgb(70,100,170,255);
    border: 1px solid rgb(70,100,170,128);
    border-radius: 3px;
    padding: 2px;
    color: #202020;
}

InvertedDigitalOutput:hover {
    background-color: rgb(70, 130, 220);
    border: None;
}

InvertedDigitalOutput:disabled{
   background-color: rgba(70,100,170,128);
   color: #505050;
}

InvertedDigitalOutput:checked {
    background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                      stop: 0 rgb(50,150,221), stop: 1 rgb(32,192,255));
    border: 1px solid #8f8f91;
    color: #000000;
}

InvertedDigitalOutput:hover:checked {
    background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                      stop: 0 rgb(50,150,221), stop: 1 rgb(120,192,255));
    border: 1px solid #8f8f91;
}

InvertedDigitalOutput:checked:disabled{
   background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                      stop: 0 rgba(50,150,221,128), stop: 1 rgba(32,192,255,128));
   color: #606060;
}
 """


[docs] def is_default_stylesheet(stylesheet): """Return whether a stylesheet is the same as the default stylesheet, modulo whitespace""" def no_whitespace(s): return "".join(s.split()) return no_whitespace(str(stylesheet)) == no_whitespace(DEFAULT_STYLESHEET)
[docs] class Plugin(object):
[docs] def __init__(self,initial_settings): self.menu = None self.notifications = {} self.BLACS = None self.initial_settings = initial_settings
[docs] def get_menu_class(self): return None
[docs] def get_notification_classes(self): return []
[docs] def get_setting_classes(self): return [Setting]
[docs] def get_callbacks(self): return {'settings_changed':self.update_stylesheet}
[docs] def update_stylesheet(self): if self.BLACS is not None: # show centralwidget as a workaround to fix stylsheets # not beeing applied under PyQt5 on first draw self.BLACS['ui'].centralwidget.show() stylesheet_settings = self.BLACS['settings'].get_value(Setting,"stylesheet") self.BLACS['ui'].centralwidget.setStyleSheet(self.unmodified_stylesheet + stylesheet_settings)
[docs] def set_menu_instance(self,menu): self.menu = menu
[docs] def set_notification_instances(self,notifications): self.notifications = notifications
[docs] def plugin_setup_complete(self, BLACS): self.BLACS = BLACS self.unmodified_stylesheet = self.BLACS['ui'].centralwidget.styleSheet() self.update_stylesheet()
[docs] def get_save_data(self): return {}
[docs] def close(self): pass
[docs] class Setting(object): name = name
[docs] def __init__(self,data): # This is our data store! self.data = data if 'stylesheet' not in self.data or not self.data['stylesheet']: # If it's absent or an empty string, use the default stylesheet: self.data['stylesheet'] = DEFAULT_STYLESHEET
[docs] def on_set_green_button_theme(self): self.widgets['stylesheet'].appendPlainText(DEFAULT_STYLESHEET)
# Create the page, return the page and an icon to use on the label (the class name attribute will be used for the label text)
[docs] def create_dialog(self,notebook): ui = UiLoader().load(os.path.join(PLUGINS_DIR, module, 'theme.ui')) # restore current stylesheet ui.stylesheet_text.setPlainText(self.data['stylesheet']) ui.example_button.clicked.connect(self.on_set_green_button_theme) # save reference to widget self.widgets = {} self.widgets['stylesheet'] = ui.stylesheet_text self.widgets['example_button'] = ui.example_button return ui,None
[docs] def get_value(self,name): if name in self.data: return self.data[name] return None
[docs] def save(self): stylesheet = str(self.widgets['stylesheet'].toPlainText()) if not stylesheet.endswith('\n'): # This is a way to distinguish between an intentionally blank # stylesheet, and an empty string, which used to be what was # stored When the user had made no changes, which now we take to # imply that they want to use the default stylesheet: stylesheet += '\n' self.data['stylesheet'] = stylesheet data = self.data.copy() if is_default_stylesheet(stylesheet): # Only save if it is not the default stylesheet: del data['stylesheet'] return data
[docs] def close(self): self.widgets['example_button'].clicked.disconnect(self.on_set_green_button_theme)