diff --git a/setup.cfg b/setup.cfg index 144ec8b4f..701190af0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 diff --git a/spinetoolbox/config.py b/spinetoolbox/config.py index 8d86c1c5b..03dcebfe0 100644 --- a/spinetoolbox/config.py +++ b/spinetoolbox/config.py @@ -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 = ( diff --git a/spinetoolbox/helpers.py b/spinetoolbox/helpers.py index 5367c60f4..e23c319eb 100644 --- a/spinetoolbox/helpers.py +++ b/spinetoolbox/helpers.py @@ -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"" date_str = get_datetime(show=show_datetime) return open_tag + date_str + message + "" @@ -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): diff --git a/spinetoolbox/spine_db_editor/widgets/multi_spine_db_editor.py b/spinetoolbox/spine_db_editor/widgets/multi_spine_db_editor.py index 8825874e5..c3400c12e 100644 --- a/spinetoolbox/spine_db_editor/widgets/multi_spine_db_editor.py +++ b/spinetoolbox/spine_db_editor/widgets/multi_spine_db_editor.py @@ -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): @@ -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)) diff --git a/spinetoolbox/ui_main.py b/spinetoolbox/ui_main.py index bcf6acb36..930d38e4d 100644 --- a/spinetoolbox/ui_main.py +++ b/spinetoolbox/ui_main.py @@ -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 @@ -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, @@ -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() @@ -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 diff --git a/spinetoolbox/widgets/add_project_item_widget.py b/spinetoolbox/widgets/add_project_item_widget.py index f07c9131b..c3ce87c7b 100644 --- a/spinetoolbox/widgets/add_project_item_widget.py +++ b/spinetoolbox/widgets/add_project_item_widget.py @@ -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()): diff --git a/spinetoolbox/widgets/custom_qtextbrowser.py b/spinetoolbox/widgets/custom_qtextbrowser.py index 32cc43f26..8ab50bb1b 100644 --- a/spinetoolbox/widgets/custom_qtextbrowser.py +++ b/spinetoolbox/widgets/custom_qtextbrowser.py @@ -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 @@ -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) diff --git a/spinetoolbox/widgets/kernel_editor.py b/spinetoolbox/widgets/kernel_editor.py index c459ee731..220bf9199 100644 --- a/spinetoolbox/widgets/kernel_editor.py +++ b/spinetoolbox/widgets/kernel_editor.py @@ -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 @@ -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.""" diff --git a/spinetoolbox/widgets/multi_tab_spec_editor.py b/spinetoolbox/widgets/multi_tab_spec_editor.py index 9b49d88b4..fc51fb0ab 100644 --- a/spinetoolbox/widgets/multi_tab_spec_editor.py +++ b/spinetoolbox/widgets/multi_tab_spec_editor.py @@ -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()) diff --git a/spinetoolbox/widgets/multi_tab_window.py b/spinetoolbox/widgets/multi_tab_window.py index f9cb5ace0..04ea71089 100644 --- a/spinetoolbox/widgets/multi_tab_window.py +++ b/spinetoolbox/widgets/multi_tab_window.py @@ -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 @@ -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: