Skip to content

Commit

Permalink
application: Reconfigure stylesheet on application palette changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ales-erjavec committed Dec 1, 2023
1 parent cbf2e9a commit 76e5981
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
3 changes: 3 additions & 0 deletions orangecanvas/application/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def maybe_match_prefix(prefix: str, path: str) -> Optional[str]:

class CanvasApplication(QApplication):
fileOpenRequest = Signal(QUrl)
applicationPaletteChanged = Signal()

__args = None

Expand Down Expand Up @@ -160,6 +161,8 @@ def event(self, event):
self.fileOpenRequest.emit(event.url())
elif event.type() == QEvent.PolishRequest:
self.configureStyle()
elif event.type() == QEvent.Type.ApplicationPaletteChange:
self.applicationPaletteChanged.emit()
return super().event(event)

def exec(self) -> int:
Expand Down
8 changes: 8 additions & 0 deletions orangecanvas/application/tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@
import time
import unittest

from AnyQt.QtGui import QPalette
from AnyQt.QtTest import QSignalSpy

from orangecanvas.utils import shtools as sh
from orangecanvas.application import application as appmod
from orangecanvas.utils.shtools import temp_named_file


def application_test_helper():
app = appmod.CanvasApplication([])
p = app.palette()
spy = QSignalSpy(app.applicationPaletteChanged)
p.setColor(QPalette.Base, p.color(QPalette.Text))
app.setPalette(p)
assert list(spy) == [[]]
app.quit()
return

Expand Down
19 changes: 19 additions & 0 deletions orangecanvas/application/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from typing import Iterable
from unittest.mock import patch, Mock

from AnyQt.QtCore import Qt
from AnyQt.QtGui import QPalette

from orangecanvas import config
from orangecanvas.application.canvasmain import CanvasMainWindow
from orangecanvas.config import Config, EntryPoint
Expand Down Expand Up @@ -131,3 +134,19 @@ def test_run_with_file(self):
res = m.run(["-", "--no-welcome", "--no-splash", fname])
CanvasMainWindow.open_scheme_file.assert_called_with(fname)
self.assertEqual(res, 42)

@with_patched_main_application
def test_run_stylesheet_reconfigure(self):
m = Main()
m.parse_arguments(["-", "--config", f"{__name__}.TestConfig"])
m.window = m.create_main_window()
m.application = self.app

def setpalette(color):
self.app.setPalette(QPalette(color))
m._Main__reconfigure_stylesheet()

setpalette(Qt.white)
sheet = m.window.styleSheet()
setpalette(Qt.black)
self.assertNotEqual(sheet, m.window.styleSheet())
16 changes: 13 additions & 3 deletions orangecanvas/main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""
"""
import argparse

import os
import sys
import gc
import logging
import pickle
import shlex
import warnings
from typing import List, Optional, IO, Any
from typing import List, Optional, IO, Any, Iterable

from urllib.request import getproxies
from contextlib import ExitStack, closing
Expand Down Expand Up @@ -176,6 +175,7 @@ def setup_application(self):
# sys.argv[0] must be in QApplication's argv list.
self.application = CanvasApplication(sys.argv[:1] + self.arguments)
self.application.setWindowIcon(self.config.application_icon())
self.application.applicationPaletteChanged.connect(self.__reconfigure_stylesheet)
# Update the arguments
self.arguments = self.application.arguments()[1:]
fix_set_proxy_env()
Expand Down Expand Up @@ -289,7 +289,7 @@ def create_main_window(self) -> CanvasMainWindow:
"""Create the (initial) main window."""
return CanvasMainWindow()

window: CanvasMainWindow
window: Optional[CanvasMainWindow] = None

def setup_main_window(self):
stylesheet = self.main_window_stylesheet()
Expand Down Expand Up @@ -377,6 +377,16 @@ def tear_down_sys_redirections(self):
if self.__stdout__ is not None:
sys.stdout = self.__stdout__

def _main_windows(self) -> Iterable[CanvasMainWindow]:
first = self.window
return (*((first,) if first else ()), *CanvasMainWindow._instances)

def __reconfigure_stylesheet(self) -> None:
ssheet = self.main_window_stylesheet()
for inst in self._main_windows():
if inst.styleSheet() != ssheet:
inst.setStyleSheet(ssheet)


def fix_win_pythonw_std_stream():
"""
Expand Down

0 comments on commit 76e5981

Please sign in to comment.