Coverage for larch/qtlib/plotarea.py: 0%

97 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1#!/usr/bin/env python 

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

3""" 

4Plot area 

5========= 

6 

7A custom QMdiArea where to add custom PlotWindows 

8 

9""" 

10import numpy as np 

11from silx.utils.weakref import WeakList 

12from silx.gui import qt 

13from .plot1D import Plot1D 

14from .plot2D import Plot2D 

15 

16 

17class MdiSubWindow(qt.QMdiSubWindow): 

18 

19 def __init__(self, parent=None): 

20 super(MdiSubWindow, self).__init__(parent=parent) 

21 self.setAttribute(qt.Qt.WA_DeleteOnClose, True) 

22 

23 def closeEvent(self, event): 

24 super(MdiSubWindow, self).closeEvent(event) 

25 # Renumber the plot windows and emit the changed signal. 

26 self.mdiArea().renumberPlotWindows() 

27 self.mdiArea().changed.emit() 

28 

29 

30class PlotArea(qt.QMdiArea): 

31 

32 changed = qt.pyqtSignal() 

33 

34 def __init__(self, parent=None): 

35 super(PlotArea, self).__init__(parent=parent) 

36 

37 #: Context menu 

38 self.setContextMenuPolicy(qt.Qt.CustomContextMenu) 

39 self.customContextMenuRequested.connect(self.showContextMenu) 

40 

41 #: Set the order of the subwindows returned by subWindowList. 

42 self.setActivationOrder(qt.QMdiArea.CreationOrder) 

43 

44 self.setWindowTitle('PlotArea') 

45 self.setMinimumSize(960, 960) 

46 self.setGeometry(0, 0, 1280, 1024) 

47 

48 def getPlotWindow(self, index): 

49 """get the PlotWindow widget object for a given index""" 

50 return self.subWindowList()[index].widget() 

51 

52 def plotWindows(self): 

53 widgets = WeakList() 

54 for subWindow in self.subWindowList(): 

55 widgets.append(subWindow.widget()) 

56 return widgets 

57 

58 def showContextMenu(self, position): 

59 menu = qt.QMenu('Plot Area Menu', self) 

60 

61 action = qt.QAction('Add Plot1D', self, 

62 triggered=self.addPlot1D) 

63 menu.addAction(action) 

64 

65 action = qt.QAction('Add Plot2D Window', self, 

66 triggered=self.addPlot2D) 

67 menu.addAction(action) 

68 

69 menu.addSeparator() 

70 

71 action = qt.QAction('Cascade Windows', self, 

72 triggered=self.cascadeSubWindows) 

73 menu.addAction(action) 

74 

75 action = qt.QAction('Tile Windows', self, 

76 triggered=self.tileSubWindows) 

77 menu.addAction(action) 

78 

79 menu.exec_(self.mapToGlobal(position)) 

80 

81 def addPlot1D(self, title=None): 

82 return self.addPlotWindow(plotType='1D', title=title) 

83 

84 def addPlot2D(self, title=None): 

85 return self.addPlotWindow(plotType='2D', title=title) 

86 

87 def addPlotWindow(self, *args, plotType='1D', title=None): 

88 """add a plot window in the mdi Area 

89 

90 Parameters 

91 ---------- 

92 plotType : str 

93 type of plot: 

94 '1D' (= curves) 

95 '2D' (= images), 

96 """ 

97 subWindow = MdiSubWindow(parent=self) 

98 if plotType == '2D': 

99 plotWindow = Plot2D(parent=subWindow, title=title) 

100 else: 

101 plotWindow = Plot1D(parent=subWindow, title=title) 

102 plotWindow.setIndex(len(self.plotWindows())) 

103 subWindow.setWidget(plotWindow) 

104 subWindow.show() 

105 self.changed.emit() 

106 return plotWindow 

107 

108 def renumberPlotWindows(self): 

109 for index, plotWindow in enumerate(self.plotWindows()): 

110 plotWindow.setIndex(index) 

111 

112 

113class PlotAreaMainWindow(qt.QMainWindow): 

114 

115 def __init__(self, app=None, parent=None): 

116 super(PlotAreaMainWindow, self).__init__(parent=parent) 

117 

118 self.app = app 

119 

120 self.plotArea = PlotArea() 

121 self.setCentralWidget(self.plotArea) 

122 

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

124 self.menuBar = qt.QMenuBar() 

125 self.setMenuBar(self.menuBar) 

126 

127 self.closeAction = qt.QAction( 

128 "&Quit", self, shortcut="Ctrl+Q", triggered=self.onClose) 

129 self._addMenuAction(self.menuBar, self.closeAction) 

130 

131 # Populate the menu bar with common actions and shortcuts 

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

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

134 invisible, its actions are still available. If deferShortcut 

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

136 will avoid conflict with shortcuts already bound to the 

137 widgets themselves. 

138 """ 

139 menu.addAction(action) 

140 self.addAction(action) 

141 

142 if deferShortcut: 

143 action.setShortcutContext(qt.Qt.WidgetShortcut) 

144 else: 

145 action.setShortcutContext(qt.Qt.ApplicationShortcut) 

146 

147 def onClose(self): 

148 self.app.lastWindowClosed.connect(qt.pyqtSignal(quit())) 

149 

150 

151def main(): 

152 global app 

153 app = qt.QApplication([]) 

154 

155 # Create the ad hoc window containing a PlotWidget and associated tools 

156 window = PlotAreaMainWindow(app) 

157 window.setAttribute(qt.Qt.WA_DeleteOnClose) 

158 window.setWindowTitle("PlotArea Main Window") 

159 window.show() 

160 

161 # Add two plot windows to the plot area. 

162 window.plotArea.addPlotWindow(plotType='1D') 

163 window.plotArea.addPlotWindow(plotType='2D') 

164 

165 plot0 = window.plotArea.getPlotWindow(0) 

166 plot1 = window.plotArea.getPlotWindow(1) 

167 

168 # Add an 1D data + 2D image to the plots 

169 x0 = np.linspace(-10, 10, 200) 

170 x1 = np.linspace(-10, 5, 150) 

171 x = np.outer(x0, x1) 

172 image = np.sin(x) / x 

173 plot0.addCurve(x0, np.sin(x0)/x0, legend='test curve 0') 

174 plot0.addCurve(x1, np.sin(x1)/x1+0.1, legend='test curve 1') 

175 plot1.addImage(image) 

176 

177 app.exec_() 

178 

179 

180if __name__ == '__main__': 

181 main()