1414"""
1515import os
1616import labscript_utils .excepthook
17+ import importlib .metadata
1718
1819# Associate app windows with OS menu shortcuts, must be before any GUI calls, apparently
1920import desktop_app
4950
5051# qt imports
5152splash .update_text ('importing qt modules' )
52- from qtutils .qt import QtCore , QtWidgets
53+ from qtutils .qt import QtCore , QtWidgets , QT_ENV
5354from qtutils .qt .QtCore import pyqtSignal as Signal
5455from qtutils import UiLoader
56+ QT_VERSION_STR = QtCore .qVersion ()
57+ PYQT_VERSION_STR = importlib .metadata .version (QT_ENV )
5558
5659# needs to be present so that qtutils icons referenced in .ui files can be resolved. Since this is
5760# magical is should not be implemented in this way.
@@ -96,6 +99,17 @@ def paintEvent(self, event):
9699 self ._previously_painted = True
97100 self .firstPaint .emit ()
98101 return result
102+
103+ def changeEvent (self , event ):
104+
105+ # theme update only for PySide6/PyQt6
106+ if QT_ENV .endswith ('6' ) and event .type () == QtCore .QEvent .Type .ThemeChange :
107+ for widget in self .findChildren (QtWidgets .QWidget ):
108+ # Complex widgets, like TreeView and TableView require triggering styleSheet and palette updates
109+ widget .setStyleSheet (widget .styleSheet ())
110+ widget .setPalette (widget .palette ())
111+
112+ return super ().changeEvent (event )
99113
100114class Lyse (object ):
101115
@@ -104,6 +118,9 @@ def __init__(self, qapplication):
104118 self .logger = setup_logging ('lyse' )
105119 labscript_utils .excepthook .set_logger (self .logger )
106120 self .logger .info ('\n \n ===============starting===============\n ' )
121+ self .logger .info (f'Qt Environment: { QT_ENV } ' )
122+ self .logger .info (f'PySide/PyQt version: { PYQT_VERSION_STR } ' )
123+ self .logger .info (f'Qt version: { QT_VERSION_STR } ' )
107124
108125 # Second: read lyse config
109126 self .setup_config ()
@@ -115,11 +132,13 @@ def __init__(self, qapplication):
115132 # Forth: start remote communication server
116133 self .port = int (self .exp_config .get ('ports' , 'lyse' ))
117134 self .server = lyse .communication .WebServer (self , self .port )
135+ self .logger .info (f'Started lyse server on port { self .port } ' )
118136
119137 # Last: UI setup
120138 self .qapplication = qapplication
121139 loader = UiLoader ()
122140 self .ui = loader .load (os .path .join (lyse .utils .LYSE_DIR , 'user_interface/main.ui' ), LyseMainWindow (self ))
141+ self .logger .info ('UI loaded' )
123142
124143 self .connect_signals ()
125144
@@ -138,6 +157,7 @@ def __init__(self, qapplication):
138157 self , to_multishot , from_multishot , self .output_box .port , multishot = True )
139158 self .filebox = lyse .filebox .FileBox (self , self .ui .verticalLayout_filebox , self .exp_config ,
140159 to_singleshot , from_singleshot , to_multishot , from_multishot )
160+ self .logger .info ('Boxes loaded' )
141161
142162 self .last_save_config_file = None
143163 self .last_save_data = None
@@ -188,6 +208,7 @@ def load_the_config_file():
188208 # Success - skip loading window geometry in load_configuration:
189209 restore_window_geometry = False
190210 self .ui .firstPaint .connect (lambda : QtCore .QTimer .singleShot (50 , load_the_config_file ))
211+ self .logger .info ('lyse configuration loaded' )
191212
192213 self .ui .show ()
193214
@@ -284,12 +305,12 @@ def get_save_data(self):
284305
285306 box = self .singleshot_routinebox
286307 save_data ['singleshot' ] = list (zip ([routine .filepath for routine in box .routines ],
287- [box .model .item (row , box .COL_ACTIVE ). checkState ()
308+ [lyse . utils . gui . get_check_state ( box .model .item (row , box .COL_ACTIVE ))
288309 for row in range (box .model .rowCount ())]))
289310 save_data ['lastsingleshotfolder' ] = box .last_opened_routine_folder
290311 box = self .multishot_routinebox
291312 save_data ['multishot' ] = list (zip ([routine .filepath for routine in box .routines ],
292- [box .model .item (row , box .COL_ACTIVE ). checkState ()
313+ [lyse . utils . gui . get_check_state ( box .model .item (row , box .COL_ACTIVE ))
293314 for row in range (box .model .rowCount ())]))
294315 save_data ['lastmultishotfolder' ] = box .last_opened_routine_folder
295316
@@ -512,6 +533,20 @@ def delete_items(self, confirm):
512533 qapplication = QtWidgets .QApplication (sys .argv )
513534 qapplication .setAttribute (QtCore .Qt .AA_DontShowIconsInMenus , False )
514535
536+ if QT_ENV .endswith ('6' ):
537+ extra_styles = """
538+ QTreeView:item:selected { color: palette(highlighted-text); }
539+
540+ QTreeView:item:hover { color: palette(highlighted-text); }
541+
542+ QTableView:item:selected { color: palette(highlighted-text); }
543+
544+ QTableView:item:hover { color: palette(highlighted-text); }
545+ """
546+
547+ current_style = qapplication .styleSheet ()
548+ qapplication .setStyleSheet (current_style + extra_styles )
549+
515550 app = Lyse (qapplication )
516551
517552 # Let the interpreter run every 500ms so it sees Ctrl-C interrupts:
@@ -522,7 +557,7 @@ def delete_items(self, confirm):
522557 signal .signal (signal .SIGINT , lambda * args : qapplication .exit ())
523558
524559 splash .hide ()
525- qapplication .exec_ ()
560+ qapplication .exec ()
526561
527562 # Shutdown the webserver.
528563 app .server .shutdown ()
0 commit comments