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
« 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
9from larch.utils.logging import getLogger
10from larch.qtlib.console import InternalIPyKernel
11from larch.qtlib.model import HeaderSection
12from larch.qtlib.delegates import ComboBoxDelegate
14from .plotrixs import RixsPlotArea
15from .view import RixsTreeView as RixsView
16from .model import RixsTreeModel as RixsModel
17from .items import RixsItem
20class RixsAppWindow(qt.QMainWindow):
21 """MainWindow may also behave as widget"""
23 def __init__(self, parent=None, with_ipykernel=True, logger=None):
24 """Constructor"""
26 self._logger = logger or getLogger('RixsAppWindow')
28 super(RixsAppWindow, self).__init__(parent=parent)
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')
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)
42 #: IPython kernel status
43 self._with_ipykernel = with_ipykernel
45 #: Model/view
46 self._model = RixsModel()
47 self._view = RixsView(parent=self)
48 self._view.setModel(self._model)
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 ]
59 for value in values:
60 section = len(self._model.header)
61 orientation = qt.Qt.Horizontal
62 self._model.setHeaderData(section, orientation, value)
64 # Add (empty) menu bar -> contents added later
65 self._menuBar = qt.QMenuBar()
66 self.setMenuBar(self._menuBar)
67 self._initAppMenu()
69 #: Plot Area
70 self._plotArea = RixsPlotArea(self)
71 self.setCentralWidget(self._plotArea)
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)
79 #: Plots update
80 self._model.dataChanged.connect(self.updatePlot)
81 self._plotArea.changed.connect(self.updateModel)
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)
92 # Add IPython console at menu
93 self._initConsoleMenu()
94 else:
95 self._ipykernel = None
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)
105 def updatePlot(self, *args):
106 topLeft, bottomRight, _ = args
108 topLeftItem = self._model.itemFromIndex(topLeft)
109 bottomRightItem = self._model.itemFromIndex(bottomRight)
111 if topLeftItem is not bottomRightItem:
112 self._logger.error('The indices do not point to the same item in the model')
113 return
115 item = topLeftItem
116 plotWindows = self._plotArea.plotWindows()
118 if item.isChecked:
119 if len(plotWindows) == 0:
120 self._logger.info('There are no plot widgets available')
121 return
123 for plotWindow in plotWindows:
124 plotWindow.remove(item.legend)
125 if not plotWindow.getItems():
126 plotWindow.reset()
127 else:
128 plotWindow.statusBar().clearMessage()
130 rixsItems = self._view.rixsItems()
131 if item.isChecked:
132 if item in list(rixsItems) and isinstance(item, RixsItem):
133 item.plot()
135 def showEvent(self, event):
136 self.loadSettings()
137 super(RixsAppWindow, self).showEvent(event)
139 def closeEvent(self, event):
140 self.saveSettings()
141 super(RixsAppWindow, self).closeEvent(event)
143 def loadSettings(self):
144 """TODO"""
145 pass
147 def saveSettings(self):
148 """TODO"""
149 pass
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)
162 if deferShortcut:
163 action.setShortcutContext(qt.Qt.WidgetShortcut)
164 else:
165 action.setShortcutContext(qt.Qt.ApplicationShortcut)
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)
174 def _initConsoleMenu(self):
175 self._menuConsole = self._menuBar.addMenu("Console")
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)
182 def onClose(self):
183 if self._ipykernel is not None:
184 self._ipykernel.cleanup_consoles()
185 self.closeEvent(quit())
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...")
196if __name__ == '__main__':
197 main()