Coverage for /Users/Newville/Codes/xraylarch/larch/qtrixs/window.py: 0%

110 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-09 10:08 -0600

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3""" 

4Application window of RIXS GUI 

5============================== 

6""" 

7from silx.gui import qt 

8 

9from larch.utils.logging import getLogger 

10from larch.qtlib.console import InternalIPyKernel 

11from larch.qtlib.model import HeaderSection 

12from larch.qtlib.delegates import ComboBoxDelegate 

13 

14from .plotrixs import RixsPlotArea 

15from .view import RixsTreeView as RixsView 

16from .model import RixsTreeModel as RixsModel 

17from .items import RixsItem 

18 

19 

20class RixsAppWindow(qt.QMainWindow): 

21 """MainWindow may also behave as widget""" 

22 

23 def __init__(self, parent=None, with_ipykernel=True, logger=None): 

24 """Constructor""" 

25 

26 self._logger = logger or getLogger('RixsAppWindow') 

27 

28 super(RixsAppWindow, self).__init__(parent=parent) 

29 

30 if parent is not None: 

31 #: behave as a widget 

32 self.setWindowFlags(qt.Qt.Widget) 

33 else: 

34 #: main window 

35 self.setWindowTitle('RIXS_VIEW') 

36 

37 # TODO: Add icon to the application 

38 #ico = qt.QIcon(os.path.join(_resourcesPath, "logo", 

39 # "xraysloth_logo_04.svg")) 

40 #self.setWindowIcon(ico) 

41 

42 #: IPython kernel status 

43 self._with_ipykernel = with_ipykernel 

44 

45 #: Model/view 

46 self._model = RixsModel() 

47 self._view = RixsView(parent=self) 

48 self._view.setModel(self._model) 

49 

50 # Add additional sections to the header. 

51 values = [ 

52 HeaderSection(name='Plot', 

53 roles={qt.Qt.DisplayRole: 'currentPlotWindowIndex', 

54 qt.Qt.EditRole: 'plotWindowsIndexes' 

55 }, 

56 delegate=ComboBoxDelegate), 

57 ] 

58 

59 for value in values: 

60 section = len(self._model.header) 

61 orientation = qt.Qt.Horizontal 

62 self._model.setHeaderData(section, orientation, value) 

63 

64 # Add (empty) menu bar -> contents added later 

65 self._menuBar = qt.QMenuBar() 

66 self.setMenuBar(self._menuBar) 

67 self._initAppMenu() 

68 

69 #: Plot Area 

70 self._plotArea = RixsPlotArea(self) 

71 self.setCentralWidget(self._plotArea) 

72 

73 #: TreeView dock widget 

74 self._dockDataWidget = qt.QDockWidget(parent=self) 

75 self._dockDataWidget.setObjectName('Data View') 

76 self._dockDataWidget.setWidget(self._view) 

77 self.addDockWidget(qt.Qt.LeftDockWidgetArea, self._dockDataWidget) 

78 

79 #: Plots update 

80 self._model.dataChanged.connect(self.updatePlot) 

81 self._plotArea.changed.connect(self.updateModel) 

82 

83 #: Console 

84 if self._with_ipykernel: 

85 # Initialize internal ipykernel 

86 self._ipykernel = InternalIPyKernel() 

87 self._ipykernel.init_kernel(backend='qt') 

88 self._ipykernel.add_to_namespace('view', self._view) 

89 self._ipykernel.add_to_namespace('model', self._model) 

90 self._ipykernel.add_to_namespace('plot', self._plotArea) 

91 

92 # Add IPython console at menu 

93 self._initConsoleMenu() 

94 else: 

95 self._ipykernel = None 

96 

97 def updateModel(self): 

98 plotWindows = self._plotArea.plotWindows() 

99 for item in self._view.rixsItems(): 

100 item.plotWindows = plotWindows 

101 if len(plotWindows) == 0: 

102 index = self._model.indexFromItem(item) 

103 self._model.dataChanged.emit(index, index) 

104 

105 def updatePlot(self, *args): 

106 topLeft, bottomRight, _ = args 

107 

108 topLeftItem = self._model.itemFromIndex(topLeft) 

109 bottomRightItem = self._model.itemFromIndex(bottomRight) 

110 

111 if topLeftItem is not bottomRightItem: 

112 self._logger.error('The indices do not point to the same item in the model') 

113 return 

114 

115 item = topLeftItem 

116 plotWindows = self._plotArea.plotWindows() 

117 

118 if item.isChecked: 

119 if len(plotWindows) == 0: 

120 self._logger.info('There are no plot widgets available') 

121 return 

122 

123 for plotWindow in plotWindows: 

124 plotWindow.remove(item.legend) 

125 if not plotWindow.getItems(): 

126 plotWindow.reset() 

127 else: 

128 plotWindow.statusBar().clearMessage() 

129 

130 rixsItems = self._view.rixsItems() 

131 if item.isChecked: 

132 if item in list(rixsItems) and isinstance(item, RixsItem): 

133 item.plot() 

134 

135 def showEvent(self, event): 

136 self.loadSettings() 

137 super(RixsAppWindow, self).showEvent(event) 

138 

139 def closeEvent(self, event): 

140 self.saveSettings() 

141 super(RixsAppWindow, self).closeEvent(event) 

142 

143 def loadSettings(self): 

144 """TODO""" 

145 pass 

146 

147 def saveSettings(self): 

148 """TODO""" 

149 pass 

150 

151 # Populate the menu bar with common actions and shortcuts 

152 def _addMenuAction(self, menu, action, deferShortcut=False): 

153 """Add action to menu as well as self so that when the menu bar is 

154 invisible, its actions are still available. If deferShortcut 

155 is True, set the shortcut context to widget-only, where it 

156 will avoid conflict with shortcuts already bound to the 

157 widgets themselves. 

158 """ 

159 menu.addAction(action) 

160 self.addAction(action) 

161 

162 if deferShortcut: 

163 action.setShortcutContext(qt.Qt.WidgetShortcut) 

164 else: 

165 action.setShortcutContext(qt.Qt.ApplicationShortcut) 

166 

167 def _initAppMenu(self): 

168 """Add application menu""" 

169 self._menuApp = self._menuBar.addMenu("Application") 

170 self._closeAppAction = qt.QAction("&Quit", self, shortcut="Ctrl+Q", 

171 triggered=self.onClose) 

172 self._addMenuAction(self._menuApp, self._closeAppAction) 

173 

174 def _initConsoleMenu(self): 

175 self._menuConsole = self._menuBar.addMenu("Console") 

176 

177 self._newConsoleAction = qt.QAction("&New Qt Console", 

178 self, shortcut="Ctrl+K", 

179 triggered=self._ipykernel.new_qt_console) 

180 self._addMenuAction(self._menuConsole, self._newConsoleAction) 

181 

182 def onClose(self): 

183 if self._ipykernel is not None: 

184 self._ipykernel.cleanup_consoles() 

185 self.closeEvent(quit()) 

186 

187 

188def main(): 

189 from silx import sx 

190 sx.enable_gui() 

191 rx = RixsAppWindow() 

192 rx.show() 

193 input("Press ENTER to close the window...") 

194 

195 

196if __name__ == '__main__': 

197 main()