Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 0 additions & 58 deletions blacs/main.ui
Original file line number Diff line number Diff line change
Expand Up @@ -24,64 +24,6 @@
padding: 4px;
}

QPushButton:hover {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #f6f7fa, stop: 1 #dadbde);
border: 1px solid #8f8f91;
border-radius: 3px;
}

QPushButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #dadbde, stop: 1 #f6f7fa);
border: 1px solid #8f8f91;
border-radius: 3px;
}

QPushButton:checked {
background-color: #dadbde;
border: 1px solid #8f8f91;
border-radius: 3px;
}

QPushButton:hover:checked {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #dadbde, stop: 1 #f6f7fa);
border: 1px solid #8f8f91;
border-radius: 3px;
}

QToolButton {
border: none;
padding: 2px;
}

QToolButton:hover {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #f6f7fa, stop: 1 #dadbde);
border: 1px solid #8f8f91;
border-radius: 3px;
}

QToolButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #dadbde, stop: 1 #f6f7fa);
border: 1px solid #8f8f91;
border-radius: 3px;
}

QToolButton:checked {
background-color: #dadbde;
border: 1px solid #8f8f91;
border-radius: 3px;
}

QToolButton:hover:checked {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #dadbde, stop: 1 #f6f7fa);
border: 1px solid #8f8f91;
border-radius: 3px;
}
</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
Expand Down
58 changes: 40 additions & 18 deletions blacs/plugins/theme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,22 @@
#####################################################################
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)

def load_theme(theme_name):
theme_path = os.path.join(PLUGINS_DIR, module, "themes", f"{theme_name}_theme.qss")
try:
with open(theme_path, "r") as f:
return f.read()
except Exception as e:
logger.warning(f"Could not load theme '{theme_name}': {e}")
return ""


DEFAULT_STYLESHEET = """DigitalOutput {
font-size: 12px;
Expand Down Expand Up @@ -99,7 +106,6 @@
}
"""


def is_default_stylesheet(stylesheet):
"""Return whether a stylesheet is the same as the default stylesheet, modulo whitespace"""

Expand Down Expand Up @@ -157,31 +163,49 @@ def close(self):
class Setting(object):
name = name

def __init__(self,data):
# This is our data store!
def __init__(self, data):
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

def on_set_green_button_theme(self):
self.widgets['stylesheet'].appendPlainText(DEFAULT_STYLESHEET)
self.data['stylesheet'] = load_theme('default') or DEFAULT_STYLESHEET

def on_set_default_theme(self):
self.widgets['stylesheet'].setPlainText(load_theme('default'))

# 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)
def create_dialog(self,notebook):
def on_set_green_button_theme(self):
self.widgets['stylesheet'].setPlainText(DEFAULT_STYLESHEET)

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'])
# Populate theme_combo with available .qss files
theme_dir = os.path.join(PLUGINS_DIR, module, 'themes')
themes = [f for f in os.listdir(theme_dir) if f.endswith('.qss')]
theme_names = [os.path.splitext(f)[0].replace('_theme','') for f in themes]
ui.theme_combo.clear()
ui.theme_combo.addItems(theme_names)
# Select current theme if possible
current_theme = None
for name in theme_names:
if load_theme(name) == self.data['stylesheet']:
current_theme = name
break
if current_theme:
idx = theme_names.index(current_theme)
ui.theme_combo.setCurrentIndex(idx)
# Handler for theme selection
def on_theme_selected(idx):
theme_name = theme_names[idx]
ui.stylesheet_text.setPlainText(load_theme(theme_name))
ui.theme_combo.currentIndexChanged.connect(on_theme_selected)
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
self.widgets['theme_combo'] = ui.theme_combo
return ui, None

def get_value(self,name):
if name in self.data:
Expand All @@ -206,5 +230,3 @@ def save(self):

def close(self):
self.widgets['example_button'].clicked.disconnect(self.on_set_green_button_theme)


21 changes: 14 additions & 7 deletions blacs/plugins/theme/theme.ui
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,20 @@
<item>
<widget class="QPlainTextEdit" name="stylesheet_text"/>
</item>
<item>
<widget class="QPushButton" name="example_button">
<property name="text">
<string>Append example green digital out theme to custom stylesheet</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="example_button">
<property name="text">
<string>Append example green digital out theme to custom stylesheet</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="theme_combo">
<property name="toolTip">
<string>Select a theme to load its stylesheet</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
Expand Down
127 changes: 127 additions & 0 deletions blacs/plugins/theme/themes/blue_theme.qss
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* ===== Global & Widget Defaults ===== */
QWidget {
background-color: #0a1224;
color: #dce7f7;
selection-background-color: #3b82f6;
selection-color: #ffffff;
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

/* ===== Push Buttons ===== */
QPushButton {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #1e2d4d, stop:1 #14213a);
border: 1px solid #24324f;
padding: 6px 10px;
border-radius: 6px;
color: #dce7f7;
}
QPushButton:hover { border-color: #3b82f6; }
QPushButton:pressed {
background-color: #2563eb;
color: #fff;
}
QPushButton:checked {
color: #dce7f7;
background-color: #2563eb;
}

/* ===== LineEdits, TextEdits ===== */
QLineEdit, QPlainTextEdit, QTextEdit {
background-color: #0f1a33;
border: 1px solid #24324f;
padding: 6px;
border-radius: 4px;
color: #dce7f7;
}
QLineEdit:focus, QTextEdit:focus { border-color: #3b82f6; }

/* ===== Tables, Headers ===== */
QHeaderView::section {
background-color: #1a2740;
color: #b8cfee;
padding: 6px;
border: 1px solid #24324f;
}
QTableView, QTreeView, QListView {
background-color: #0d162b;
gridline-color: #1e2d4d;
alternate-background-color: #101b33;
}
QTableView::item:selected, QTreeView::item:selected, QListView::item:selected {
background-color: #3b82f6;
color: #fff;
}

/* ===== Combo & Spin Boxes ===== */
QComboBox, QSpinBox, QDoubleSpinBox {
background-color: #0f1a33;
border: 1px solid #24324f;
padding: 4px;
color: #dce7f7;
}

/* ===== Checkboxes / Radios ===== */
QCheckBox, QRadioButton { spacing: 6px; }
QCheckBox::indicator, QRadioButton::indicator {
background-color: transparent;
border: 1px solid #3b4e72;
}

/* ===== Progress Bar ===== */
QProgressBar {
border: 1px solid #24324f;
background: #0f1a33;
text-align: center;
border-radius: 6px;
}
QProgressBar::chunk {
background-color: #60a5fa; /* brighter blue chunk */
border-radius: 6px;
}

/* ===== Tabs ===== */
QTabWidget::pane { border: 1px solid #24324f; }
QTabBar::tab {
background: #0a1224;
color: #b8cfee;
padding: 8px;
border: 1px solid #24324f;
border-bottom: none;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
QTabBar::tab:selected { background: #1a2740; color: #fff; }

/* ===== Dock Widgets ===== */
QDockWidget { titlebar-close-icon: url(:/icons/close.png); title: " "; }
QDockWidget::title { background: #14213a; color: #dce7f7; }

/* ===== Menus & Tooltips ===== */
QMenuBar, QMenu {
background-color: #0a1224;
color: #dce7f7;
}
QMenu::item:selected { background-color: #2563eb; color: #fff; }
QToolTip {
background-color: #1a2740;
color: #dce7f7;
border: 1px solid #3b4e72;
padding: 6px;
}

/* ===== Scrollbars & Splitters ===== */
QScrollBar:vertical {
background: #0a1224;
width: 12px;
}
QScrollBar::handle:vertical {
background: #24324f;
min-height: 20px;
border-radius: 6px;
}
QScrollBar::add-line, QScrollBar::sub-line { height: 0px; }
QSplitter::handle { background: #1a2740; }

/* ===== Status Bar ===== */
QStatusBar { background: #0a1224; color: #b8cfee; }
Loading