def __init__(self, app, tree, confirm_exit, config=None): """ Create a MainWindow for the application Parameters ---------- app : reference to QApplication parent """ super(MainWindow, self).__init__() self.resize(1000, 800) self._app = app self._app.setStyle("QMacStyle") self.config = config self.confirm_exit = confirm_exit self.default_directory = os.path.expanduser('~') self.copied_node = None mainwindow = QtGui.QWidget() rightpane = QtGui.QWidget() self.plotview = NXPlotView(parent=rightpane) self.plotview.setMinimumSize(700, 600) self.console = IPythonWidget(config=self.config, parent=rightpane) self.console.setMinimumSize(700, 200) self.console.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) self.console._confirm_exit = self.confirm_exit self.console.gui_completion = 'droplist' self.console.kernel_manager = QtKernelManager(config=self.config) self.console.kernel_manager.start_kernel() self.console.kernel_manager.start_channels() self.shell = self.console.kernel_manager.kernel.shell self.user_ns = self.console.kernel_manager.kernel.shell.user_ns rightlayout = QtGui.QVBoxLayout() rightlayout.addWidget(self.plotview) rightlayout.addWidget(self.console) rightlayout.setContentsMargins(0, 0, 0, 0) rightpane.setLayout(rightlayout) self.tree = tree self.treeview = NXTreeView(self.tree,parent=mainwindow) self.treeview.setMinimumWidth(200) self.treeview.setMaximumWidth(400) self.treeview.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.user_ns['plotview'] = self.plotview self.user_ns['treeview'] = self.treeview self.user_ns['tree'] = self.tree self.user_ns['mainwindow'] = self mainlayout = QtGui.QHBoxLayout() mainlayout.addWidget(self.treeview) mainlayout.addWidget(rightpane) mainlayout.setContentsMargins(0, 0, 0, 0) mainwindow.setLayout(mainlayout) self.setCentralWidget(mainwindow) base_path = os.path.abspath(os.path.dirname(__file__)) icon_path = os.path.join(base_path, 'resources', 'icon', 'NeXpy.svg') self.import_path = os.path.join(os.path.abspath(os.path.dirname(base_path)), 'readers') self._app.icon = QtGui.QIcon(icon_path) QtGui.QApplication.setWindowIcon(self._app.icon) self.init_menu_bar() self.setWindowTitle('NeXpy') self.statusBar().showMessage('Ready') self.console._control.setFocus()
class MainWindow(QtGui.QMainWindow): #--------------------------------------------------------------------------- # 'object' interface #--------------------------------------------------------------------------- def __init__(self, app, tree, confirm_exit, config=None): """ Create a MainWindow for the application Parameters ---------- app : reference to QApplication parent """ super(MainWindow, self).__init__() self.resize(1000, 800) self._app = app self._app.setStyle("QMacStyle") self.config = config self.confirm_exit = confirm_exit self.default_directory = os.path.expanduser('~') self.copied_node = None mainwindow = QtGui.QWidget() rightpane = QtGui.QWidget() self.plotview = NXPlotView(parent=rightpane) self.plotview.setMinimumSize(700, 600) self.console = IPythonWidget(config=self.config, parent=rightpane) self.console.setMinimumSize(700, 200) self.console.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) self.console._confirm_exit = self.confirm_exit self.console.gui_completion = 'droplist' self.console.kernel_manager = QtKernelManager(config=self.config) self.console.kernel_manager.start_kernel() self.console.kernel_manager.start_channels() self.shell = self.console.kernel_manager.kernel.shell self.user_ns = self.console.kernel_manager.kernel.shell.user_ns rightlayout = QtGui.QVBoxLayout() rightlayout.addWidget(self.plotview) rightlayout.addWidget(self.console) rightlayout.setContentsMargins(0, 0, 0, 0) rightpane.setLayout(rightlayout) self.tree = tree self.treeview = NXTreeView(self.tree,parent=mainwindow) self.treeview.setMinimumWidth(200) self.treeview.setMaximumWidth(400) self.treeview.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.user_ns['plotview'] = self.plotview self.user_ns['treeview'] = self.treeview self.user_ns['tree'] = self.tree self.user_ns['mainwindow'] = self mainlayout = QtGui.QHBoxLayout() mainlayout.addWidget(self.treeview) mainlayout.addWidget(rightpane) mainlayout.setContentsMargins(0, 0, 0, 0) mainwindow.setLayout(mainlayout) self.setCentralWidget(mainwindow) base_path = os.path.abspath(os.path.dirname(__file__)) icon_path = os.path.join(base_path, 'resources', 'icon', 'NeXpy.svg') self.import_path = os.path.join(os.path.abspath(os.path.dirname(base_path)), 'readers') self._app.icon = QtGui.QIcon(icon_path) QtGui.QApplication.setWindowIcon(self._app.icon) self.init_menu_bar() self.setWindowTitle('NeXpy') self.statusBar().showMessage('Ready') self.console._control.setFocus() def close(self,current): """ Called when you need to try to close the console widget. """ title = self.window().windowTitle() cancel = QtGui.QMessageBox.Cancel okay = QtGui.QMessageBox.Ok reply = QtGui.QMessageBox.question(self, title, "Are you sure you want to close this Console?"+ "\nThe Kernel and other Consoles will remain active.", okay|cancel, defaultButton=okay) if reply == okay: pass # Populate the menu bar with common actions and shortcuts def add_menu_action(self, menu, action, defer_shortcut=False): """Add action to menu as well as self So that when the menu bar is invisible, its actions are still available. If defer_shortcut is True, set the shortcut context to widget-only, where it will avoid conflict with shortcuts already bound to the widgets themselves. """ menu.addAction(action) self.addAction(action) if defer_shortcut: action.setShortcutContext(QtCore.Qt.WidgetShortcut) def init_menu_bar(self): #create menu in the order they should appear in the menu bar self.init_file_menu() self.init_edit_menu() self.init_data_menu() self.init_view_menu() self.init_magic_menu() self.init_window_menu() self.init_help_menu() def init_file_menu(self): self.file_menu = self.menuBar().addMenu("&File") self.file_menu.addSeparator() self.newworkspace_action=QtGui.QAction("&New...", self, shortcut=QtGui.QKeySequence.New, triggered=self.new_workspace ) self.add_menu_action(self.file_menu, self.newworkspace_action, True) self.openfile_action=QtGui.QAction("&Open (read only)", self, shortcut=QtGui.QKeySequence.Open, triggered=self.open_file ) self.add_menu_action(self.file_menu, self.openfile_action, True) self.openeditablefile_action=QtGui.QAction("Open (read/write)", self, shortcut=QtGui.QKeySequence("Ctrl+Shift+O"), triggered=self.open_editable_file ) self.add_menu_action(self.file_menu, self.openeditablefile_action, True) self.savefile_action=QtGui.QAction("&Save", self, shortcut=QtGui.QKeySequence.Save, triggered=self.save_file ) self.add_menu_action(self.file_menu, self.savefile_action, True) self.savefileas_action=QtGui.QAction("Save as...", self, shortcut=QtGui.QKeySequence.SaveAs, triggered=self.save_file_as ) self.add_menu_action(self.file_menu, self.savefileas_action, True) self.file_menu.addSeparator() self.init_import_menu() self.file_menu.addSeparator() printkey = QtGui.QKeySequence(QtGui.QKeySequence.Print) if printkey.matches("Ctrl+P") and sys.platform != 'darwin': # Only override the default if there is a collision. # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX. printkey = "Ctrl+Shift+P" self.print_action = QtGui.QAction("&Print Shell", self, shortcut=printkey, triggered=self.print_action_console) self.add_menu_action(self.file_menu, self.print_action, True) if sys.platform != 'darwin': # OSX always has Quit in the Application menu, only add it # to the File menu elsewhere. self.file_menu.addSeparator() self.quit_action = QtGui.QAction("&Quit", self, shortcut=QtGui.QKeySequence.Quit, triggered=self.close, ) self.add_menu_action(self.file_menu, self.quit_action) def init_edit_menu(self): self.edit_menu = self.menuBar().addMenu("&Edit") self.undo_action = QtGui.QAction("&Undo", self, shortcut=QtGui.QKeySequence.Undo, statusTip="Undo last action if possible", triggered=self.undo_console ) self.add_menu_action(self.edit_menu, self.undo_action) self.redo_action = QtGui.QAction("&Redo", self, shortcut=QtGui.QKeySequence.Redo, statusTip="Redo last action if possible", triggered=self.redo_console) self.add_menu_action(self.edit_menu, self.redo_action) self.edit_menu.addSeparator() self.cut_action = QtGui.QAction("&Cut", self, shortcut=QtGui.QKeySequence.Cut, triggered=self.cut_console ) self.add_menu_action(self.edit_menu, self.cut_action, True) self.copy_action = QtGui.QAction("&Copy", self, shortcut=QtGui.QKeySequence.Copy, triggered=self.copy_console ) self.add_menu_action(self.edit_menu, self.copy_action, True) self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)", self, shortcut="Ctrl+Shift+C", triggered=self.copy_raw_console ) self.add_menu_action(self.edit_menu, self.copy_raw_action, True) self.paste_action = QtGui.QAction("&Paste", self, shortcut=QtGui.QKeySequence.Paste, triggered=self.paste_console ) self.add_menu_action(self.edit_menu, self.paste_action, True) self.edit_menu.addSeparator() selectall = QtGui.QKeySequence(QtGui.QKeySequence.SelectAll) if selectall.matches("Ctrl+A") and sys.platform != 'darwin': # Only override the default if there is a collision. # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX. selectall = "Ctrl+Shift+A" self.select_all_action = QtGui.QAction("Select &All", self, shortcut=selectall, triggered=self.select_all_console ) self.add_menu_action(self.edit_menu, self.select_all_action, True) def init_data_menu(self): self.data_menu = self.menuBar().addMenu("Data") self.plot_data_action=QtGui.QAction("Plot Data", self, triggered=self.plot_data ) self.add_menu_action(self.data_menu, self.plot_data_action, True) self.overplot_data_action=QtGui.QAction("Overplot Data", self, triggered=self.overplot_data ) self.add_menu_action(self.data_menu, self.overplot_data_action, True) self.data_menu.addSeparator() self.add_action=QtGui.QAction("Add Data", self, triggered=self.add_data ) self.add_menu_action(self.data_menu, self.add_action, True) self.rename_action=QtGui.QAction("Rename Data", self, triggered=self.rename_data ) self.add_menu_action(self.data_menu, self.rename_action, True) self.copy_action=QtGui.QAction("Copy Data", self, triggered=self.copy_data ) self.add_menu_action(self.data_menu, self.copy_action, True) self.paste_action=QtGui.QAction("Paste Data", self, triggered=self.paste_data ) self.add_menu_action(self.data_menu, self.paste_action, True) self.delete_action=QtGui.QAction("Delete Data", self, triggered=self.delete_data ) self.add_menu_action(self.data_menu, self.delete_action, True) self.data_menu.addSeparator() self.signal_action=QtGui.QAction("Set Signal", self, triggered=self.set_signal ) self.add_menu_action(self.data_menu, self.signal_action, True) self.data_menu.addSeparator() self.fit_action=QtGui.QAction("Fit Data", self, triggered=self.fit_data ) self.add_menu_action(self.data_menu, self.fit_action, True) def init_view_menu(self): self.view_menu = self.menuBar().addMenu("&View") if sys.platform != 'darwin': # disable on OSX, where there is always a menu bar self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar", self, shortcut="Ctrl+Shift+M", statusTip="Toggle visibility of menubar", triggered=self.toggle_menu_bar) self.add_menu_action(self.view_menu, self.toggle_menu_bar_act) fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11" self.full_screen_act = QtGui.QAction("&Full Screen", self, shortcut=fs_key, statusTip="Toggle between Fullscreen and Normal Size", triggered=self.toggleFullScreen) self.add_menu_action(self.view_menu, self.full_screen_act) self.view_menu.addSeparator() self.increase_font_size = QtGui.QAction("Zoom &In", self, shortcut=QtGui.QKeySequence.ZoomIn, triggered=self.increase_font_size_console ) self.add_menu_action(self.view_menu, self.increase_font_size, True) self.decrease_font_size = QtGui.QAction("Zoom &Out", self, shortcut=QtGui.QKeySequence.ZoomOut, triggered=self.decrease_font_size_console ) self.add_menu_action(self.view_menu, self.decrease_font_size, True) self.reset_font_size = QtGui.QAction("Zoom &Reset", self, shortcut="Ctrl+0", triggered=self.reset_font_size_console ) self.add_menu_action(self.view_menu, self.reset_font_size, True) self.view_menu.addSeparator() self.clear_action = QtGui.QAction("&Clear Screen", self, shortcut='Ctrl+L', statusTip="Clear the console", triggered=self.clear_magic_console) self.add_menu_action(self.view_menu, self.clear_action) def init_import_menu(self): """Add an import menu item for every module in self.import_path""" self.import_names = set() self.import_menu = self.file_menu.addMenu("Import") private_path = os.path.join(os.path.expanduser('~'), '.nexpy', 'readers') if os.path.isdir(private_path): sys.path.append(private_path) for file in os.listdir(private_path): name, ext = os.path.splitext(file) if name <> '__init__' and ext.startswith('.py'): self.import_names.add(name) sys.path.append(self.import_path) for file in os.listdir(self.import_path): name, ext = os.path.splitext(file) if name <> '__init__' and ext.startswith('.py'): self.import_names.add(name) self.importer = {} for import_name in sorted(self.import_names): fp, pathname, description = imp.find_module(import_name) try: import_module = imp.load_module(import_name, fp, pathname, description) finally: if fp: fp.close() import_action = QtGui.QAction("Import "+import_module.filetype, self, triggered=self.show_import_dialog) self.add_menu_action(self.import_menu, import_action, self) self.importer[import_action] = import_module def show_import_dialog(self): import_module = self.importer[self.sender()] self.import_dialog = import_module.ImportDialog() self.import_dialog.show() def import_data(self): if self.import_dialog.accepted: workspace = self.treeview.tree.get_new_name() self.treeview.tree[workspace] = self.import_dialog.get_data() def new_workspace(self): default_name = self.treeview.tree.get_new_name() name, ok = QtGui.QInputDialog.getText(self, 'New Workspace', 'Workspace Name:', text=default_name) if name and ok: self.treeview.tree[name] = NXroot(NXentry()) def open_file(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open File (Read Only)', self.default_directory, "NeXus Files (*.nxs *.nx5 *.h5 *.nx4 *.hdf *.xml)") workspace = self.treeview.tree.get_name(fname) self.treeview.tree[workspace] = self.user_ns[workspace] = nxload(fname) self.default_directory = os.path.dirname(fname) def open_editable_file(self): fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open File (Read/Write)', self.default_directory, "NeXus Files (*.nxs *.nx5 *.h5 *.nx4 *.hdf *.xml)") workspace = self.treeview.tree.get_name(fname) self.treeview.tree[workspace] = self.user_ns[workspace] = nxload(fname, 'rw') self.default_directory = os.path.dirname(fname) def save_file(self): node = self.treeview.getnode() if node is None: return elif node.nxfile and isinstance(node, NXroot): try: node.save() except NeXusError, error_message: QtGui.QMessageBox.critical( self, "Error saving file", str(error_message), QtGui.QMessageBox.Ok, QtGui.QMessageBox.NoButton) else: