3232import time
3333from pathlib import Path
3434import platform
35+ import importlib .metadata
3536WINDOWS = platform .system () == 'Windows'
3637
3738# No splash update for Qt - the splash code has already imported it:
3839from qtutils import inmain_decorator , inmain_later , inmain , inthread , UiLoader
3940import qtutils .icons # import has side-effects we rely on
40- from qtutils .qt .QtCore import PYQT_VERSION_STR , QT_VERSION_STR , QTimer , Qt
41- from qtutils .qt .QtGui import QIcon
41+ from qtutils .qt .QtCore import QTimer , Qt , qVersion , QEvent
42+ from qtutils .qt .QtGui import QIcon , QColor , QPalette
4243from qtutils .qt .QtWidgets import (
4344 QMainWindow ,
4445 QToolButton ,
4546 QMessageBox ,
4647 QFileDialog ,
47- QApplication
48+ QApplication ,
49+ QWidget
4850)
4951from qtutils .qt import QT_ENV
52+ PYQT_VERSION_STR = importlib .metadata .version (QT_ENV )
5053
5154
5255splash .update_text ("importing zmq and zprocess" )
8487logger .info (f'h5py version: { h5py .version .info } ' )
8588logger .info (f'Qt enviroment: { QT_ENV } ' )
8689logger .info (f'PySide/PyQt version: { PYQT_VERSION_STR } ' )
87- logger .info (f'Qt version: { QT_VERSION_STR } ' )
90+ logger .info (f'Qt version: { qVersion () } ' )
8891logger .info (f'qtutils version: { qtutils .__version__ } ' )
8992logger .info (f'zprocess version: { zprocess .__version__ } ' )
9093logger .info (f'labscript_utils version: { labscript_utils .__version__ } ' )
@@ -141,6 +144,23 @@ def closeEvent(self, event):
141144
142145 QTimer .singleShot (100 ,self .close )
143146
147+ def changeEvent (self , event ):
148+
149+ # theme update only for PySide6/PyQt6
150+ if QT_ENV .endswith ('6' ) and event .type () == QEvent .Type .ThemeChange :
151+ for widget in self .findChildren (QWidget ):
152+ # Complex widgets, like TreeView and TableView require triggering styleSheet and palette updates
153+ widget .setStyleSheet (widget .styleSheet ())
154+ widget .setPalette (widget .palette ())
155+ # tab header text colors have to be done explicitly by tab
156+ # because they use setTabTextColor
157+ app = QApplication .instance ()
158+ self .blacs .update_all_tab_icon_and_text (
159+ app .palette ().color (QPalette .ColorRole .Text )
160+ )
161+
162+ return super ().changeEvent (event )
163+
144164
145165class EasterEggButton (QToolButton ):
146166 def __init__ (self ):
@@ -530,14 +550,23 @@ def update_all_tab_settings(self,settings,tab_data):
530550 self .settings_dict [tab_name ]["saved_data" ] = tab_data [tab_name ]['data' ] if tab_name in tab_data else {}
531551 tab .update_from_settings (self .settings_dict [tab_name ])
532552
553+ def update_all_tab_icon_and_text (self , text_colour ):
554+ # used to repaint tab header text after theme change
555+
556+ for tab in self .tablist .values ():
557+ if tab ._tab_text_colour == QColor ('red' ):
558+ # ensure error tabs keep their red text
559+ continue
560+ tab ._tab_text_colour = text_colour
561+ tab .set_tab_icon_and_colour ()
533562
534563 def on_load_front_panel (self ,* args ,** kwargs ):
535564 # get the file:
536565 # create file chooser dialog
537566 dialog = QFileDialog (None ,"Select file to load" , self .exp_config .get ('paths' ,'experiment_shot_storage' ), "HDF5 files (*.h5 *.hdf5)" )
538567 dialog .setViewMode (QFileDialog .Detail )
539568 dialog .setFileMode (QFileDialog .ExistingFile )
540- if dialog .exec_ ():
569+ if dialog .exec ():
541570 selected_files = dialog .selectedFiles ()
542571 filepath = str (selected_files [0 ])
543572 # Qt has this weird behaviour where if you type in the name of a file that exists
@@ -556,7 +585,7 @@ def on_load_front_panel(self,*args,**kwargs):
556585 message .setWindowTitle ("BLACS" )
557586 message .setStandardButtons (QMessageBox .Yes | QMessageBox .No )
558587
559- if message .exec_ () == QMessageBox .Yes :
588+ if message .exec () == QMessageBox .Yes :
560589 front_panel_settings = FrontPanelSettings (filepath , self .connection_table )
561590 settings ,question ,error ,tab_data = front_panel_settings .restore ()
562591 #TODO: handle question/error
@@ -588,7 +617,7 @@ def on_load_front_panel(self,*args,**kwargs):
588617 message .setText ("Unable to load the front panel. The error encountered is printed below.\n \n %s" % str (e ))
589618 message .setIcon (QMessageBox .Information )
590619 message .setWindowTitle ("BLACS" )
591- message .exec_ ()
620+ message .exec ()
592621 finally :
593622 dialog .deleteLater ()
594623 else :
@@ -597,7 +626,7 @@ def on_load_front_panel(self,*args,**kwargs):
597626 message .setText ("You did not select a file ending with .h5 or .hdf5. Please try again" )
598627 message .setIcon (QMessageBox .Information )
599628 message .setWindowTitle ("BLACS" )
600- message .exec_ ()
629+ message .exec ()
601630 QTimer .singleShot (10 ,self .on_load_front_panel )
602631
603632 def on_save_exit (self ):
@@ -684,7 +713,7 @@ def on_save_front_panel(self,*args,**kwargs):
684713 dialog .setFileMode (QFileDialog .AnyFile )
685714 dialog .setAcceptMode (QFileDialog .AcceptSave )
686715
687- if dialog .exec_ ():
716+ if dialog .exec ():
688717 current_file = str (dialog .selectedFiles ()[0 ])
689718 if not current_file .endswith ('.h5' ):
690719 current_file += '.h5'
@@ -780,6 +809,6 @@ def process(self,h5_filepath):
780809 splash .hide ()
781810
782811 def execute_program ():
783- qapplication .exec_ ()
812+ qapplication .exec ()
784813
785814 sys .exit (execute_program ())
0 commit comments