def __init__(self): Qt.QMainWindow.__init__(self, None) # "application main window", # Qt.WType_TopLevel | Qt.WDestructiveClose) self.file_menu = Qt.QMenu('&File',self) self.file_menu.addAction('&Quit', self.fileQuit, Qt.Qt.CTRL + Qt.Qt.Key_Q) self.menuBar().addMenu(self.file_menu) self.help_menu = Qt.QMenu('&Help', self) self.menuBar().addSeparator() self.menuBar().addMenu(self.help_menu) self.help_menu.addAction('&About', self.about) self.main_widget = Qt.QWidget(self) l = Qt.QVBoxLayout(self.main_widget) sc = MyPylabPlotter(self.main_widget, dpi=100) toolbar = NavigationToolbar(sc, self.main_widget) toolbar.setSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Fixed) l.addWidget(sc) l.addWidget(toolbar) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) # Produce a plot that is contained in MyPylabPlotter sc.demo_pythonic_matplotlib() # Produce a plot that is separate from MyPylabPlotter sc.demo_pylab_figure()
def __init__(self): Qt.QMainWindow.__init__(self, None) # "application main window", # Qt.WType_TopLevel | Qt.WDestructiveClose) self.file_menu = Qt.QMenu("&File", self) self.file_menu.addAction("&Quit", self.fileQuit, Qt.Qt.CTRL + Qt.Qt.Key_Q) self.menuBar().addMenu(self.file_menu) self.help_menu = Qt.QMenu("&Help", self) self.menuBar().addSeparator() self.menuBar().addMenu(self.help_menu) self.help_menu.addAction("&About", self.about) self.main_widget = Qt.QWidget(self) l = Qt.QVBoxLayout(self.main_widget) sc = MyPylabPlotter(self.main_widget, dpi=100) toolbar = NavigationToolbar(sc, self.main_widget) toolbar.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed) l.addWidget(sc) l.addWidget(toolbar) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) # Produce a plot that is contained in MyPylabPlotter sc.demo_pythonic_matplotlib() # Produce a plot that is separate from MyPylabPlotter sc.demo_pylab_figure()
def init_plots(self): """ Initialize plots used in plugin """ self.plot_dock = QtGui.QDockWidget('TSTools Plots', self.iface.mainWindow()) self.plot_dock.setObjectName('TSTools Plots') settings.plot_dirty = [] for plot in plots.plots: self.plots.append(plot(self.iface)) settings.plot_dirty.append(False) self.plot_tabs = QtGui.QTabWidget(self.plot_dock) @QtCore.pyqtSlot(int) def tab_changed(idx): """ Updates current tab index & re-plots if needed """ settings.plot_current = idx if settings.plot_dirty[idx]: self.plots[idx].plot() settings.plot_dirty[idx] = False self.plot_tabs.currentChanged.connect(tab_changed) for plot in self.plots: widget = QtGui.QWidget() layout = QtGui.QHBoxLayout() nav = NavigationToolbar(plot, widget, coordinates=False) nav.setOrientation(QtCore.Qt.Vertical) nav.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) plot.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) layout.addWidget(nav) layout.addWidget(plot) widget.setLayout(layout) self.plot_tabs.addTab(widget, plot.__str__()) self.plot_dock.setWidget(self.plot_tabs) self.iface.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.plot_dock)
class PylabPlotter(GriddedPlugin): """ a class to visualize data from external pylab graphics files """ _icon = pixmaps.bars3d viewer_name = "Pylab Plotter"; def is_viewable (data): return len(data) > 0; is_viewable = staticmethod(is_viewable); def __init__(self,gw,dataitem,cellspec={},**opts): GriddedPlugin.__init__(self,gw,dataitem,cellspec=cellspec); """ a plugin for showing pylab plots """ self._rec = None; self._wtop = None; self.dataitem = dataitem self.png_number = 0 self.data_list = [] self.data_list_labels = [] self.data_list_length = 0 self.max_list_length = 50 self.layout_created = False self.counter = -1 self.reset_plot_stuff() # back to 'real' work if dataitem and dataitem.data is not None: self.set_data(dataitem); def reset_plot_stuff(self): """ resets widgets to None. Needed if we have been putting out a message about Cache not containing results, etc """ self._pylab_plotter = None self._toolbar = None self.results_selector = None self.status_label = None self.layout_parent = None self.layout = None def wtop (self): """ function needed by Oleg for reasons known only to him! """ return self._wtop; def create_layout_stuff(self): """ create grid layouts into which plotter widgets are inserted """ if self.layout_parent is None or not self.layout_created: self.layout_parent = Qt.QWidget(self.wparent()) self.layout = Qt.QGridLayout(self.layout_parent) self.set_widgets(self.layout_parent,self.dataitem.caption,icon=self.icon()) self.layout_created = True self._wtop = self.layout_parent; def set_data (self,dataitem,default_open=None,**opts): """ this callback receives data from the meqbrowser, when the user has requested a plot. It decides whether the data is from a VellSet or visu data record, and after any necessary preprocssing forwards the data to one of the functions which does the actual plotting """ _dprint(3, '** in pylab_plotter:set_data callback') if not has_pylab: Message = "Matplotlib does not appear to be installed so no plot can be made." cache_message = Qt.QLabel(Message,self.wparent()) # cache_message.setTextFormat(Qt.RichText) self._wtop = cache_message self.set_widgets(cache_message) self.reset_plot_stuff() return self._rec = dataitem.data; _dprint(3, 'set_data: initial self._rec ', self._rec) # if we are single stepping through requests, Oleg may reset the # cache, so check for a non-data record situation if self._rec is None: return if isinstance(self._rec, bool): return self.label = ''; # extra label, filled in if possible # there's a problem here somewhere ... if dmi_typename(self._rec) != 'MeqResult': # data is not already a result? # try to put request ID in label rq_id_found = False data_failure = False try: if self._rec.cache.has_key("request_id"): self.label = "rq " + str(self._rec.cache.request_id); rq_id_found = True if self._rec.cache.has_key("result"): self._rec = self._rec.cache.result; # look for cache.result record if not rq_id_found and self._rec.has_key("request_id"): self.label = "rq " + str(self._rec.request_id); else: data_failure = True _dprint(3, 'we have req id ', self.label) except: data_failure = True if data_failure: _dprint(3, ' we have a data failure') # cached_result not found, display an empty viewer with a "no result # in this node record" message (the user can then use the Display with # menu to switch to a different viewer) Message = "No cache result record was found for this node, so no plot can be made." cache_message = Qt.QLabel(Message,self.wparent()) # cache_message.setTextFormat(Qt.RichText) self._wtop = cache_message self.set_widgets(cache_message) self.reset_plot_stuff() return # update display with current data process_result = self.process_data() # add this data set to internal list for later replay if process_result: if self.max_list_length > 0: self.data_list.append(self._rec) self.data_list_labels.append(self.label) if len(self.data_list_labels) > self.max_list_length: del self.data_list_labels[0] del self.data_list[0] if len(self.data_list) != self.data_list_length: self.data_list_length = len(self.data_list) if self.data_list_length > 1: _dprint(3, 'calling adjust_selector') self.adjust_selector() def process_data (self): """ process the actual record structure associated with a Cache result """ process_result = False # are we dealing with an pylab result? if self._rec.has_key("plotdefs"): self.create_layout_stuff() self.show_pylab_plot() process_result = True # enable & highlight the cell self.enable(); self.flash_refresh(); _dprint(3, 'exiting process_data') return process_result def replay_data (self, data_index): """ call to redisplay contents of a result record stored in a results history buffer """ if data_index < len(self.data_list): self._rec = self.data_list[data_index] self.label = self.data_list_labels[data_index] self.results_selector.setLabel(self.label) process_result = self.process_data() def show_pylab_plot(self, store_rec=True): """ process incoming data and attributes into the appropriate type of plot """ # if we are single stepping through requests, Oleg may reset the # cache, so check for a non-data record situation if store_rec and isinstance(self._rec, bool): return pylab_record = self._rec.plotdefs if not self._pylab_plotter is None: # self._pylab_plotter.reparent(Qt.QWidget(), 0, Qt.QPoint()) self._pylab_plotter.setParent(Qt.QWidget()) self._pylab_plotter = None if not self._toolbar is None: # self._toolbar.reparent(Qt.QWidget(), 0, Qt.QPoint()) self._toolbar.setParent(Qt.QWidget()) self._toolbar = None if self._pylab_plotter is None: self._pylab_plotter = MyPylabPlotter(parent=self.layout_parent) self.layout.addWidget(self._pylab_plotter,1,0) self._pylab_plotter.show() if self._toolbar is None: self._toolbar = NavigationToolbar(self._pylab_plotter, self.layout_parent) self._toolbar.setSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Fixed) self.layout.addWidget(self._toolbar,0,0) self._toolbar.show() self._pylab_plotter.make_plot(pylab_record) # end show_pylab_plot() def set_results_buffer (self, result_value): """ callback to set the number of results records that can be stored in a results history buffer """ if result_value < 0: return self.max_list_length = result_value if len(self.data_list_labels) > self.max_list_length: differ = len(self.data_list_labels) - self.max_list_length for i in range(differ): del self.data_list_labels[0] del self.data_list[0] if len(self.data_list) != self.data_list_length: self.data_list_length = len(self.data_list) self.show_pylab_plot(store_rec=False) def adjust_selector (self): """ instantiate and/or adjust contents of ResultsRange object """ if self.results_selector is None: self.results_selector = ResultsRange(self.layout_parent) self.results_selector.setMaxValue(self.max_list_length) self.results_selector.set_offset_index(0) self.results_selector.setSizePolicy(Qt.QSizePolicy.Expanding,Qt.QSizePolicy.Minimum) self.layout.addWidget(self.results_selector,2,0) self.results_selector.show() QObject.connect(self.results_selector, PYSIGNAL('result_index'), self.replay_data) QObject.connect(self.results_selector, PYSIGNAL('adjust_results_buffer_size'), self.set_results_buffer) self.results_selector.set_emit(False) self.results_selector.setRange(self.data_list_length-1) self.results_selector.setLabel(self.label) self.results_selector.set_emit(True)
class PylabPlotter(GriddedPlugin): """ a class to visualize data from external pylab graphics files """ _icon = pixmaps.bars3d viewer_name = "Pylab Plotter" def is_viewable(data): return len(data) > 0 is_viewable = staticmethod(is_viewable) def __init__(self, gw, dataitem, cellspec={}, **opts): GriddedPlugin.__init__(self, gw, dataitem, cellspec=cellspec) """ a plugin for showing pylab plots """ self._rec = None self._wtop = None self.dataitem = dataitem self.png_number = 0 self.data_list = [] self.data_list_labels = [] self.data_list_length = 0 self.max_list_length = 50 self.layout_created = False self.counter = -1 self.reset_plot_stuff() # back to 'real' work if dataitem and dataitem.data is not None: self.set_data(dataitem) def reset_plot_stuff(self): """ resets widgets to None. Needed if we have been putting out a message about Cache not containing results, etc """ self._pylab_plotter = None self._toolbar = None self.results_selector = None self.status_label = None self.layout_parent = None self.layout = None def wtop(self): """ function needed by Oleg for reasons known only to him! """ return self._wtop def create_layout_stuff(self): """ create grid layouts into which plotter widgets are inserted """ if self.layout_parent is None or not self.layout_created: self.layout_parent = Qt.QWidget(self.wparent()) self.layout = Qt.QGridLayout(self.layout_parent) self.set_widgets(self.layout_parent, self.dataitem.caption, icon=self.icon()) self.layout_created = True self._wtop = self.layout_parent def set_data(self, dataitem, default_open=None, **opts): """ this callback receives data from the meqbrowser, when the user has requested a plot. It decides whether the data is from a VellSet or visu data record, and after any necessary preprocssing forwards the data to one of the functions which does the actual plotting """ _dprint(3, "** in pylab_plotter:set_data callback") if not has_pylab: Message = "Matplotlib does not appear to be installed so no plot can be made." cache_message = Qt.QLabel(Message, self.wparent()) # cache_message.setTextFormat(Qt.RichText) self._wtop = cache_message self.set_widgets(cache_message) self.reset_plot_stuff() return self._rec = dataitem.data _dprint(3, "set_data: initial self._rec ", self._rec) # if we are single stepping through requests, Oleg may reset the # cache, so check for a non-data record situation if self._rec is None: return if isinstance(self._rec, bool): return self.label = "" # extra label, filled in if possible # there's a problem here somewhere ... if dmi_typename(self._rec) != "MeqResult": # data is not already a result? # try to put request ID in label rq_id_found = False data_failure = False try: if self._rec.cache.has_key("request_id"): self.label = "rq " + str(self._rec.cache.request_id) rq_id_found = True if self._rec.cache.has_key("result"): self._rec = self._rec.cache.result # look for cache.result record if not rq_id_found and self._rec.has_key("request_id"): self.label = "rq " + str(self._rec.request_id) else: data_failure = True _dprint(3, "we have req id ", self.label) except: data_failure = True if data_failure: _dprint(3, " we have a data failure") # cached_result not found, display an empty viewer with a "no result # in this node record" message (the user can then use the Display with # menu to switch to a different viewer) Message = "No cache result record was found for this node, so no plot can be made." cache_message = Qt.QLabel(Message, self.wparent()) # cache_message.setTextFormat(Qt.RichText) self._wtop = cache_message self.set_widgets(cache_message) self.reset_plot_stuff() return # update display with current data process_result = self.process_data() # add this data set to internal list for later replay if process_result: if self.max_list_length > 0: self.data_list.append(self._rec) self.data_list_labels.append(self.label) if len(self.data_list_labels) > self.max_list_length: del self.data_list_labels[0] del self.data_list[0] if len(self.data_list) != self.data_list_length: self.data_list_length = len(self.data_list) if self.data_list_length > 1: _dprint(3, "calling adjust_selector") self.adjust_selector() def process_data(self): """ process the actual record structure associated with a Cache result """ process_result = False # are we dealing with an pylab result? if self._rec.has_key("plotdefs"): self.create_layout_stuff() self.show_pylab_plot() process_result = True # enable & highlight the cell self.enable() self.flash_refresh() _dprint(3, "exiting process_data") return process_result def replay_data(self, data_index): """ call to redisplay contents of a result record stored in a results history buffer """ if data_index < len(self.data_list): self._rec = self.data_list[data_index] self.label = self.data_list_labels[data_index] self.results_selector.setLabel(self.label) process_result = self.process_data() def show_pylab_plot(self, store_rec=True): """ process incoming data and attributes into the appropriate type of plot """ # if we are single stepping through requests, Oleg may reset the # cache, so check for a non-data record situation if store_rec and isinstance(self._rec, bool): return pylab_record = self._rec.plotdefs if not self._pylab_plotter is None: # self._pylab_plotter.reparent(Qt.QWidget(), 0, Qt.QPoint()) self._pylab_plotter.setParent(Qt.QWidget()) self._pylab_plotter = None if not self._toolbar is None: # self._toolbar.reparent(Qt.QWidget(), 0, Qt.QPoint()) self._toolbar.setParent(Qt.QWidget()) self._toolbar = None if self._pylab_plotter is None: self._pylab_plotter = MyPylabPlotter(parent=self.layout_parent) self.layout.addWidget(self._pylab_plotter, 1, 0) self._pylab_plotter.show() if self._toolbar is None: self._toolbar = NavigationToolbar(self._pylab_plotter, self.layout_parent) self._toolbar.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed) self.layout.addWidget(self._toolbar, 0, 0) self._toolbar.show() self._pylab_plotter.make_plot(pylab_record) # end show_pylab_plot() def set_results_buffer(self, result_value): """ callback to set the number of results records that can be stored in a results history buffer """ if result_value < 0: return self.max_list_length = result_value if len(self.data_list_labels) > self.max_list_length: differ = len(self.data_list_labels) - self.max_list_length for i in range(differ): del self.data_list_labels[0] del self.data_list[0] if len(self.data_list) != self.data_list_length: self.data_list_length = len(self.data_list) self.show_pylab_plot(store_rec=False) def adjust_selector(self): """ instantiate and/or adjust contents of ResultsRange object """ if self.results_selector is None: self.results_selector = ResultsRange(self.layout_parent) self.results_selector.setMaxValue(self.max_list_length) self.results_selector.set_offset_index(0) self.results_selector.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) self.layout.addWidget(self.results_selector, 2, 0) self.results_selector.show() QObject.connect(self.results_selector, PYSIGNAL("result_index"), self.replay_data) QObject.connect(self.results_selector, PYSIGNAL("adjust_results_buffer_size"), self.set_results_buffer) self.results_selector.set_emit(False) self.results_selector.setRange(self.data_list_length - 1) self.results_selector.setLabel(self.label) self.results_selector.set_emit(True)