Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Os provided theme support #1953

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ install_requires =
jill >=0.9.2
pyzmq >=21.0
spine-items >= 0.17.0
pyqtdarktheme >= 2.0
include_package_data = True
python_requires = >=3.8.1, <3.12

Expand Down
71 changes: 37 additions & 34 deletions spinetoolbox/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,48 +59,51 @@
PROJECT_ZIP_FILENAME = "project_package" # ZIP-file name for remote execution

# Stylesheets
STATUSBAR_SS = "QStatusBar{background-color: #EBEBE0; border-width: 1px; border-color: gray; border-style: groove;}"
STATUSBAR_SS = ""
# STATUSBAR_SS = "QStatusBar{background-color: #EBEBE0; border-width: 1px; border-color: gray; border-style: groove;}"

BG_COLOR = "#19232D"
FG_COLOR = "#F0F0F0"

SETTINGS_SS = (
"#SettingsForm{background-color: ghostwhite;}"
"QLabel{color: black;}"
"QGroupBox{border: 2px solid gray; "
"background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #80B0FF, stop: 1 #e6efff);"
"border-radius: 5px;"
"margin-top: 0.5em;}"
"QGroupBox:title{border-radius: 2px; "
"background-color: ghostwhite;"
"subcontrol-origin: margin;"
"subcontrol-position: top center;"
"padding-top: 0px;"
"padding-bottom: 0px;"
"padding-right: 3px;"
"padding-left: 3px;}"
"QCheckBox{outline-style: dashed; outline-width: 1px; outline-color: white;}"
f"QPushButton{{background-color: #505F69; border: 1px solid #29353d; color: {FG_COLOR}; border-radius: 4px; padding: 3px; outline: none; min-width:80px}}"
"QPushButton:disabled {background-color: #32414B; border: 1px solid #29353d; color: #787878; border-radius: 4px; padding: 3px;}"
"QPushButton::menu-indicator {subcontrol-origin: padding; subcontrol-position: bottom right; bottom: 4px;}"
"QPushButton:focus{background-color: #637683; border: 1px solid #148CD2;}"
f"QPushButton:hover{{border: 1px solid #148CD2; color: {FG_COLOR};}}"
f"QPushButton:pressed{{background-color: {BG_COLOR}; border: 1px solid {BG_COLOR};}}"
"QSlider::groove:horizontal{background: #e1e1e1; border: 1px solid #a4a4a4; height: 5px; margin: 2px 0; border-radius: 2px;}"
"QSlider::handle:horizontal{background: #fafafa; border: 1px solid #a4a4a4; width: 12px; margin: -5px 0; border-radius: 2px;}"
"QSlider::add-page:horizontal{background: transparent;}"
"QSlider::sub-page:horizontal{background: transparent;}"
)
SETTINGS_SS = ""
# SETTINGS_SS = (
# "#SettingsForm{background-color: ghostwhite;}"
# "QLabel{color: black;}"
# "QGroupBox{border: 2px solid gray; "
# "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #80B0FF, stop: 1 #e6efff);"
# "border-radius: 5px;"
# "margin-top: 0.5em;}"
# "QGroupBox:title{border-radius: 2px; "
# "background-color: ghostwhite;"
# "subcontrol-origin: margin;"
# "subcontrol-position: top center;"
# "padding-top: 0px;"
# "padding-bottom: 0px;"
# "padding-right: 3px;"
# "padding-left: 3px;}"
# "QCheckBox{outline-style: dashed; outline-width: 1px; outline-color: white;}"
# f"QPushButton{{background-color: #505F69; border: 1px solid #29353d; color: {FG_COLOR}; border-radius: 4px; padding: 3px; outline: none; min-width:80px}}"
# "QPushButton:disabled {background-color: #32414B; border: 1px solid #29353d; color: #787878; border-radius: 4px; padding: 3px;}"
# "QPushButton::menu-indicator {subcontrol-origin: padding; subcontrol-position: bottom right; bottom: 4px;}"
# "QPushButton:focus{background-color: #637683; border: 1px solid #148CD2;}"
# f"QPushButton:hover{{border: 1px solid #148CD2; color: {FG_COLOR};}}"
# f"QPushButton:pressed{{background-color: {BG_COLOR}; border: 1px solid {BG_COLOR};}}"
# "QSlider::groove:horizontal{background: #e1e1e1; border: 1px solid #a4a4a4; height: 5px; margin: 2px 0; border-radius: 2px;}"
# "QSlider::handle:horizontal{background: #fafafa; border: 1px solid #a4a4a4; width: 12px; margin: -5px 0; border-radius: 2px;}"
# "QSlider::add-page:horizontal{background: transparent;}"
# "QSlider::sub-page:horizontal{background: transparent;}"
# )

# ICON_BACKGROUND = "qlineargradient(x1: 1, y1: 1, x2: 0, y2: 0, stop: 0 #cce0ff, stop: 1 #66a1ff);"
# ICON_TOOLBAR_SS = f"QToolBar{{spacing: 6px; background: {ICON_BACKGROUND}; padding: 3px; border-style: solid;}}"

TEXTBROWSER_SS = (
f"QTextBrowser {{background-color: {BG_COLOR}; border: 1px solid #32414B; color: {FG_COLOR}; border-radius: 2px;}}"
"QTextBrowser:hover,"
"QTextBrowser:selected,"
"QTextBrowser:pressed {border: 1px solid #668599;}"
)
TEXTBROWSER_SS = ""
# TEXTBROWSER_SS = (
# f"QTextBrowser {{background-color: {BG_COLOR}; border: 1px solid #32414B; color: {FG_COLOR}; border-radius: 2px;}}"
# "QTextBrowser:hover,"
# "QTextBrowser:selected,"
# "QTextBrowser:pressed {border: 1px solid #668599;}"
# )

# ToolboxUI stylesheet. A lot of widgets inherit this sheet.
MAINWINDOW_SS = (
Expand Down
5 changes: 3 additions & 2 deletions spinetoolbox/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def format_log_message(msg_type, message, show_datetime=True):
Returns:
str: formatted message
"""
color = {"msg": "white", "msg_success": "#00ff00", "msg_error": "#ff3333", "msg_warning": "yellow"}[msg_type]
color = {"msg": "", "msg_success": "#00ff00", "msg_error": "#ff3333", "msg_warning": "yellow"}[msg_type]
open_tag = f"<span style='color:{color};white-space: pre-wrap;'>"
date_str = get_datetime(show=show_datetime)
return open_tag + date_str + message + "</span>"
Expand Down Expand Up @@ -1008,7 +1008,8 @@ def make_icon_background(color):
def make_icon_toolbar_ss(color):
icon_background = make_icon_background(color)
# NOTE: border-style property needs to be set for QToolBar so the lineargradient works on GNOME desktop environment
return f"QToolBar{{spacing: 0px; background: {icon_background}; padding: 3px; border-style: solid;}}"
# return f"QToolBar{{spacing: 0px; background: {icon_background}; padding: 3px; border-style: solid;}}"
return ""


def color_from_index(i, count, base_hue=0.0, saturation=1.0):
Expand Down
2 changes: 0 additions & 2 deletions spinetoolbox/spine_db_editor/widgets/multi_spine_db_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from ...helpers import CharIconEngine, open_url
from ...config import ONLINE_DOCUMENTATION_URL
from ...widgets.settings_widget import SpineDBEditorSettingsWidget
from ...config import MAINWINDOW_SS


class MultiSpineDBEditor(MultiTabWindow):
Expand All @@ -44,7 +43,6 @@ def __init__(self, db_mngr, db_url_codenames=None):
self.db_mngr.fetcher_waiting_over.connect(self._close_waiting_for_fetcher)
self._waiting_box = None
self.settings_form = SpineDBEditorSettingsWidget(self)
self.setStyleSheet(MAINWINDOW_SS)
self.setWindowTitle("Spine DB Editor")
self.setWindowIcon(QIcon(":/symbols/app.ico"))
self.setStatusBar(_CustomStatusBar(self))
Expand Down
6 changes: 3 additions & 3 deletions spinetoolbox/ui_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
QVBoxLayout,
QHBoxLayout,
)
import qdarktheme
from spine_engine.load_project_items import load_item_specification_factories
from spine_items.category import CATEGORIES, CATEGORY_DESCRIPTIONS
from .project_item_icon import ProjectItemIcon
Expand All @@ -82,7 +83,7 @@
from .spine_db_manager import SpineDBManager
from .spine_db_editor.widgets.multi_spine_db_editor import MultiSpineDBEditor
from .spine_engine_manager import make_engine_manager
from .config import MAINWINDOW_SS, DEFAULT_WORK_DIR, ONLINE_DOCUMENTATION_URL
from .config import DEFAULT_WORK_DIR, ONLINE_DOCUMENTATION_URL
from .helpers import (
create_dir,
ensure_window_is_on_screen,
Expand Down Expand Up @@ -154,8 +155,6 @@ def __init__(self):
self.ui.tabWidget_item_properties.installEventFilter(self.key_press_filter)
self._share_item_edit_actions()
self.ui.listView_console_executions.setModel(FilterExecutionModel(self))
# Set style sheets
self.setStyleSheet(MAINWINDOW_SS)
# Class variables
self.undo_stack = QUndoStack(self)
self._item_categories = dict()
Expand Down Expand Up @@ -230,6 +229,7 @@ def __init__(self):
self.set_work_directory()
self._disable_project_actions()
self.connect_signals()
qdarktheme.setup_theme("auto")

def eventFilter(self, obj, ev):
# Save/restore splitter states when hiding/showing execution lists
Expand Down
2 changes: 1 addition & 1 deletion spinetoolbox/widgets/add_project_item_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, toolbox, x, y, class_, spec=""):
self.statusbar = QStatusBar(self)
self.statusbar.setFixedHeight(20)
self.statusbar.setSizeGripEnabled(False)
self.statusbar.setStyleSheet(STATUSBAR_SS)
# self.statusbar.setStyleSheet(STATUSBAR_SS)
self.ui.horizontalLayout_statusbar_placeholder.addWidget(self.statusbar)
# Init
if toolbox.supports_specifications(class_.item_type()):
Expand Down
2 changes: 0 additions & 2 deletions spinetoolbox/widgets/custom_qtextbrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from PySide6.QtCore import Slot
from PySide6.QtGui import QTextCursor, QFontDatabase, QTextBlockFormat, QTextFrameFormat, QBrush, QAction, QPalette
from PySide6.QtWidgets import QTextBrowser, QMenu
from ..config import TEXTBROWSER_SS
from ..helpers import scrolling_to_bottom


Expand All @@ -37,7 +36,6 @@ def __init__(self, parent):
super().__init__(parent=parent)
self._toolbox = None
self.document().setMaximumBlockCount(2000)
self.setStyleSheet(TEXTBROWSER_SS)
self.setOpenExternalLinks(True)
self.setOpenLinks(False) # Don't try open file:/// links in the browser widget, we'll open them externally
self._executions_menu = QMenu(self)
Expand Down
2 changes: 0 additions & 2 deletions spinetoolbox/widgets/kernel_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
ensure_window_is_on_screen,
get_datetime,
)
from spinetoolbox.config import MAINWINDOW_SS
from spinetoolbox.logger_interface import LoggerInterface
from spinetoolbox.helpers import unique_name

Expand Down Expand Up @@ -74,7 +73,6 @@ def setup_dialog_style(self):
This can be removed when SettingsWidget
inherits stylesheet from ToolboxUI."""
self.setWindowIcon(QIcon(":/symbols/app.ico"))
self.setStyleSheet(MAINWINDOW_SS)

def connect_signals(self):
"""Connects signals to slots."""
Expand Down
2 changes: 1 addition & 1 deletion spinetoolbox/widgets/multi_tab_spec_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
class MultiTabSpecEditor(MultiTabWindow):
def __init__(self, toolbox, item_type):
super().__init__(toolbox.qsettings(), f"{item_type}SpecEditor")
self.setStyleSheet(toolbox.styleSheet())
# self.setStyleSheet(toolbox.styleSheet())
self._toolbox = toolbox
self.item_type = item_type
self.setWindowTitle(f"{item_type} specification editor".capitalize())
Expand Down
5 changes: 4 additions & 1 deletion spinetoolbox/widgets/multi_tab_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, qsettings, settings_group):
self.settings_group = settings_group
self.tab_widget = QTabWidget(self)
self.tab_bar = TabBarPlus(self)
self.tab_widget.setTabBar(self.tab_bar)
self.tab_widget.setTabBar(self.tab_bar) # This sets mouseTracking on for self.tab_bar. Bug in pyqtdarktheme.
self.setCentralWidget(self.tab_widget)
self.setAttribute(Qt.WA_DeleteOnClose)
self._hot_spot = None
Expand Down Expand Up @@ -508,6 +508,9 @@ def mousePressEvent(self, event):

def mouseMoveEvent(self, event):
"""Detaches a tab either if the user moves beyond the limits of the tab bar, or if it's the only one."""
print(f"mouseTracking:{self.hasMouseTracking()} self._hot_spot_y:{self._hot_spot_y}")
if not self._hot_spot_y: # This is a hacky effort to deal with the bug in pyqtdarktheme
return
if self.count() > 0:
self._plus_button.hide()
if self.count() == 1:
Expand Down