def __init__(self, parent=None, qtapp=None): super().__init__(parent) self.qtapp = qtapp self.mdi = QMdiArea() self.setCentralWidget(self.mdi) self.app_manager = AppManager(None, gui_parent=self) self.mdi.subWindowActivated.connect(self.app_manager. on_view_activated) self.is_dark = self.light_or_dark(False) self.left = 100 self.top = 50 self.width = 1800 self.height = 1200 self.setGeometry(self.left, self.top, self.width, self.height) bar = self.menuBar() file_menu = bar.addMenu("File") file_menu.addAction("New") file_menu.addAction("Open...") file_menu.addSeparator() file_menu.addAction("Save") file_menu.addAction("Save As...") file_menu.addAction("Close") file_menu.triggered[QAction].connect(self.file_action) view_menu = bar.addMenu("Data View") view_menu.addAction("Spec Sheet") view_menu.addAction("Optical Layout") view_menu.addAction("Lens Table") view_menu.addAction("Element Table") view_menu.addAction("Glass Map") # view_menu.addAction("Lens View") view_menu.triggered[QAction].connect(self.view_action) parax_menu = bar.addMenu("Paraxial Model") parax_menu.addAction("Paraxial Model") parax_menu.addAction("y-ybar View") parax_menu.addAction("nu-nubar View") parax_menu.addAction("yui Ray Table") parax_menu.addAction("3rd Order Aberrations") parax_menu.triggered[QAction].connect(self.view_action) analysis_menu = bar.addMenu("Analysis") analysis_menu.addAction("Ray Table") analysis_menu.addAction("Ray Fans") analysis_menu.addAction("OPD Fans") analysis_menu.addAction("Spot Diagram") analysis_menu.addAction("Wavefront Map") analysis_menu.addAction("Astigmatism Curves") analysis_menu.triggered[QAction].connect(self.view_action) tools_menu = bar.addMenu("Tools") tools_menu.addAction("Paraxial Vignetting") tools_menu.triggered[QAction].connect(self.view_action) wnd_menu = bar.addMenu("Window") wnd_menu.addAction("Cascade") wnd_menu.addAction("Tiled") wnd_menu.addSeparator() wnd_menu.addAction("Light UI") wnd_menu.addAction("Dark UI") wnd_menu.addSeparator() dock.create_dock_windows(self) for pi in dock.panels.values(): wnd_menu.addAction(pi.menu_action) wnd_menu.triggered[QAction].connect(self.window_action) self.setWindowTitle("Ray Optics") self.show() path = Path(rayoptics.__file__).parent self.cur_dir = path / "models" if False: # create new model self.new_model() else: # restore a default model # self.cur_dir = path / "codev/tests" # self.open_file(path / "codev/tests/asp46.seq") # self.open_file(path / "codev/tests/dar_test.seq") # self.open_file(path / "codev/tests/paraboloid.seq") # self.open_file(path / "codev/tests/paraboloid_f8.seq") # self.open_file(path / "codev/tests/schmidt.seq") # self.open_file(path / "codev/tests/questar35.seq") # self.open_file(path / "codev/tests/rc_f16.seq") # self.open_file(path / "codev/tests/ag_dblgauss.seq") # self.open_file(path / "codev/tests/threemir.seq") # self.open_file(path / "codev/tests/folded_lenses.seq") # self.open_file(path / "codev/tests/lens_reflection_test.seq") # self.open_file(path / "codev/tests/dec_tilt_test.seq") # self.open_file(path / "codev/tests/landscape_lens.seq") # self.open_file(path / "codev/tests/mangin.seq") # self.open_file(path / "codev/tests/CODV_32327.seq") # self.open_file(path / "codev/tests/dar_test.seq") # self.open_file(path / "optical/tests/cell_phone_camera.roa") # self.open_file(path / "optical/tests/singlet_f3.roa") # self.cur_dir = path / "models" # self.open_file(path / "models/Cassegrain.roa") # self.open_file(path / "models/collimator.roa") # self.open_file(path / "models/Dall-Kirkham.roa") # self.open_file(path / "models/petzval.roa") # self.open_file(path / "models/Ritchey_Chretien.roa") # self.open_file(path / "models/Sasian Triplet.roa") # self.open_file(path / "models/singlet_f5.roa") # self.open_file(path / "models/thinlens.roa") # self.open_file(path / "models/telephoto.roa") # self.open_file(path / "models/thin_triplet.roa") # self.open_file(path / "models/TwoMirror.roa") # self.open_file(path / "models/TwoSphericalMirror.roa") self.cur_dir = path / "zemax/tests" # self.open_file(path / "zemax/tests/US08427765-1.ZMX") # self.open_file(path / "zemax/tests/US00583336-2-scaled.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex03.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex27.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex46.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex66.zmx") # self.open_file(path / "zemax/tests/US05831776-1.zmx") self.open_file(path / "zemax/tests/354710-C-Zemax(ZMX).zmx")
class MainWindow(QMainWindow): count = 0 def __init__(self, parent=None, qtapp=None): super().__init__(parent) self.qtapp = qtapp self.mdi = QMdiArea() self.setCentralWidget(self.mdi) self.app_manager = AppManager(None, gui_parent=self) self.mdi.subWindowActivated.connect(self.app_manager. on_view_activated) self.is_dark = self.light_or_dark(False) self.left = 100 self.top = 50 self.width = 1800 self.height = 1200 self.setGeometry(self.left, self.top, self.width, self.height) bar = self.menuBar() file_menu = bar.addMenu("File") file_menu.addAction("New") file_menu.addAction("Open...") file_menu.addSeparator() file_menu.addAction("Save") file_menu.addAction("Save As...") file_menu.addAction("Close") file_menu.triggered[QAction].connect(self.file_action) view_menu = bar.addMenu("Data View") view_menu.addAction("Spec Sheet") view_menu.addAction("Optical Layout") view_menu.addAction("Lens Table") view_menu.addAction("Element Table") view_menu.addAction("Glass Map") # view_menu.addAction("Lens View") view_menu.triggered[QAction].connect(self.view_action) parax_menu = bar.addMenu("Paraxial Model") parax_menu.addAction("Paraxial Model") parax_menu.addAction("y-ybar View") parax_menu.addAction("nu-nubar View") parax_menu.addAction("yui Ray Table") parax_menu.addAction("3rd Order Aberrations") parax_menu.triggered[QAction].connect(self.view_action) analysis_menu = bar.addMenu("Analysis") analysis_menu.addAction("Ray Table") analysis_menu.addAction("Ray Fans") analysis_menu.addAction("OPD Fans") analysis_menu.addAction("Spot Diagram") analysis_menu.addAction("Wavefront Map") analysis_menu.addAction("Astigmatism Curves") analysis_menu.triggered[QAction].connect(self.view_action) tools_menu = bar.addMenu("Tools") tools_menu.addAction("Paraxial Vignetting") tools_menu.triggered[QAction].connect(self.view_action) wnd_menu = bar.addMenu("Window") wnd_menu.addAction("Cascade") wnd_menu.addAction("Tiled") wnd_menu.addSeparator() wnd_menu.addAction("Light UI") wnd_menu.addAction("Dark UI") wnd_menu.addSeparator() dock.create_dock_windows(self) for pi in dock.panels.values(): wnd_menu.addAction(pi.menu_action) wnd_menu.triggered[QAction].connect(self.window_action) self.setWindowTitle("Ray Optics") self.show() path = Path(rayoptics.__file__).parent self.cur_dir = path / "models" if False: # create new model self.new_model() else: # restore a default model # self.cur_dir = path / "codev/tests" # self.open_file(path / "codev/tests/asp46.seq") # self.open_file(path / "codev/tests/dar_test.seq") # self.open_file(path / "codev/tests/paraboloid.seq") # self.open_file(path / "codev/tests/paraboloid_f8.seq") # self.open_file(path / "codev/tests/schmidt.seq") # self.open_file(path / "codev/tests/questar35.seq") # self.open_file(path / "codev/tests/rc_f16.seq") # self.open_file(path / "codev/tests/ag_dblgauss.seq") # self.open_file(path / "codev/tests/threemir.seq") # self.open_file(path / "codev/tests/folded_lenses.seq") # self.open_file(path / "codev/tests/lens_reflection_test.seq") # self.open_file(path / "codev/tests/dec_tilt_test.seq") # self.open_file(path / "codev/tests/landscape_lens.seq") # self.open_file(path / "codev/tests/mangin.seq") # self.open_file(path / "codev/tests/CODV_32327.seq") # self.open_file(path / "codev/tests/dar_test.seq") # self.open_file(path / "optical/tests/cell_phone_camera.roa") # self.open_file(path / "optical/tests/singlet_f3.roa") # self.cur_dir = path / "models" # self.open_file(path / "models/Cassegrain.roa") # self.open_file(path / "models/collimator.roa") # self.open_file(path / "models/Dall-Kirkham.roa") # self.open_file(path / "models/petzval.roa") # self.open_file(path / "models/Ritchey_Chretien.roa") # self.open_file(path / "models/Sasian Triplet.roa") # self.open_file(path / "models/singlet_f5.roa") # self.open_file(path / "models/thinlens.roa") # self.open_file(path / "models/telephoto.roa") # self.open_file(path / "models/thin_triplet.roa") # self.open_file(path / "models/TwoMirror.roa") # self.open_file(path / "models/TwoSphericalMirror.roa") self.cur_dir = path / "zemax/tests" # self.open_file(path / "zemax/tests/US08427765-1.ZMX") # self.open_file(path / "zemax/tests/US00583336-2-scaled.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex03.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex27.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex46.zmx") # self.open_file(path / "zemax/tests/HoO-V2C18Ex66.zmx") # self.open_file(path / "zemax/tests/US05831776-1.zmx") self.open_file(path / "zemax/tests/354710-C-Zemax(ZMX).zmx") # self.cur_dir = path / "zemax/models/telescopes" # self.open_file(path / "zemax/models/telescopes/Figure4.zmx") # self.open_file(path / "zemax/models/telescopes/HoO-V2C18Ex11.zmx") # self.cur_dir = path / "zemax/models/PhotoPrime" # self.open_file(path / "zemax/models/PhotoPrime/US05321554-4.ZMX") # self.open_file(path / "zemax/models/PhotoPrime/US06476982-1.ZMX") # self.open_file(path / "zemax/models/PhotoPrime/US07190532-1.ZMX") # self.open_file(path / "zemax/models/PhotoPrime/US04331391-1.zmx") # self.open_file(path / "zemax/models/PhotoPrime/US05331467-1.zmx") def add_subwindow(self, widget, model_info): sub_wind = self.mdi.addSubWindow(widget) self.app_manager.add_view(sub_wind, widget, model_info) MainWindow.count += 1 return sub_wind def delete_subwindow(self, sub_wind): self.app_manager.delete_view(sub_wind) self.mdi.removeSubWindow(sub_wind) MainWindow.count -= 1 def add_ipython_subwindow(self): try: create_ipython_console(self, 'iPython console', 800, 600) except MultipleInstanceError: logging.debug("Unable to open iPython console. " "MultipleInstanceError") except Exception as inst: print(type(inst)) # the exception instance print(inst.args) # arguments stored in .args print(inst) # __str__ allows args to be printed directly, pass # but may be overridden in exception subclasses def initial_window_offset(self): offset_x = 50 offset_y = 25 orig_x = (MainWindow.count - 1)*offset_x orig_y = (MainWindow.count - 1)*offset_y return orig_x, orig_y def file_action(self, q): if q.text() == "New": self.new_model() if q.text() == "Open...": options = QFileDialog.Options() # options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", str(self.cur_dir), "All files (*.seq *.zmx *.roa);;" "CODE V files (*.seq);;" "Ray-Optics files (*.roa);;" "Zemax files (*.zmx)", options=options) if fileName: logging.debug("open file: %s", fileName) filename = Path(fileName) self.cur_dir = filename.parent self.open_file(filename) if q.text() == "Save As...": options = QFileDialog.Options() # options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName( self, "QFileDialog.getSaveFileName()", "", "Ray-Optics Files (*.roa);;All Files (*)", options=options) if fileName: logging.debug("save file: %s", fileName) self.save_file(fileName) if q.text() == "Close": self.close_model() def new_model(self): iid = cmds.create_new_ideal_imager(gui_parent=self, conjugate_type='infinite') self.add_ipython_subwindow() self.refresh_app_ui() def open_file(self, file_name, **kwargs): self.cur_filename = file_name opt_model = cmds.open_model(file_name, **kwargs) self.app_manager.set_model(opt_model) self.is_changed = True self.create_lens_table() cmds.create_live_layout_view(self.app_manager.model, gui_parent=self) self.add_ipython_subwindow() self.refresh_app_ui() def save_file(self, file_name): self.app_manager.model.save_model(file_name) self.cur_filename = file_name self.is_changed = False def close_model(self): """ NOTE: this does not check to save a modified model """ self.app_manager.close_model(self.delete_subwindow) def view_action(self, q): opt_model = self.app_manager.model if q.text() == "Spec Sheet": cmds.create_new_ideal_imager(opt_model=opt_model, gui_parent=self) if q.text() == "Optical Layout": cmds.create_live_layout_view(opt_model, gui_parent=self) if q.text() == "Lens Table": self.create_lens_table() if q.text() == "Element Table": model = cmds.create_element_table_model(opt_model) self.create_table_view(model, "Element Table") if q.text() == "Glass Map": cmds.create_glass_map_view(opt_model, gui_parent=self) if q.text() == "Ray Fans": cmds.create_ray_fan_view(opt_model, "Ray", gui_parent=self) if q.text() == "OPD Fans": cmds.create_ray_fan_view(opt_model, "OPD", gui_parent=self) if q.text() == "Spot Diagram": cmds.create_ray_grid_view(opt_model, gui_parent=self) if q.text() == "Wavefront Map": cmds.create_wavefront_view(opt_model, gui_parent=self) if q.text() == "Astigmatism Curves": cmds.create_field_curves(opt_model, gui_parent=self) if q.text() == "3rd Order Aberrations": cmds.create_3rd_order_bar_chart(opt_model, gui_parent=self) if q.text() == "y-ybar View": cmds.create_paraxial_design_view_v2(opt_model, 'ht', gui_parent=self) if q.text() == "nu-nubar View": cmds.create_paraxial_design_view_v2(opt_model, 'slp', gui_parent=self) if q.text() == "yui Ray Table": model = cmds.create_parax_table_model(opt_model) self.create_table_view(model, "Paraxial Ray Table") if q.text() == "Paraxial Model": model = cmds.create_parax_model_table(opt_model) self.create_table_view(model, "Paraxial Model") if q.text() == "Ray Table": self.create_ray_table(opt_model) if q.text() == "Paraxial Vignetting": trace.apply_paraxial_vignetting(opt_model) self.refresh_gui() def window_action(self, q): if q.text() == "Cascade": self.mdi.cascadeSubWindows() if q.text() == "Tiled": self.mdi.tileSubWindows() if q.text() == "Light UI": self.is_dark = self.light_or_dark(False) self.app_manager.sync_light_or_dark(self.is_dark) if q.text() == "Dark UI": self.is_dark = self.light_or_dark(True) self.app_manager.sync_light_or_dark(self.is_dark) def light_or_dark(self, is_dark): """ set the UI to a light or dark scheme. Qt doesn't seem to support controlling the MdiArea's background from a style sheet. Set the widget directly and save the original color to reset defaults. """ if not hasattr(self, 'mdi_background'): self.mdi_background = self.mdi.background() if is_dark: self.qtapp.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) rgb = DarkPalette.color_palette() self.mdi.setBackground(QColor(rgb['COLOR_BACKGROUND_NORMAL'])) else: self.qtapp.setStyleSheet('') self.mdi.setBackground(self.mdi_background) return is_dark def create_lens_table(self): seq_model = self.app_manager.model.seq_model def set_stop_surface(stop_surface): seq_model.stop_surface = stop_surface self.refresh_gui() def handle_context_menu(point): try: vheader = view.verticalHeader() row = vheader.logicalIndexAt(point.y()) except NameError: pass else: # show menu about the row menu = QMenu(self) if row != seq_model.stop_surface: menu.addAction('Set Stop Surface', lambda: set_stop_surface(row)) if seq_model.stop_surface is not None: menu.addAction('Float Stop Surface', lambda: set_stop_surface(None)) menu.popup(vheader.mapToGlobal(point)) model = cmds.create_lens_table_model(seq_model) view = self.create_table_view(model, "Surface Data Table") vheader = view.verticalHeader() vheader.setContextMenuPolicy(qt.CustomContextMenu) vheader.customContextMenuRequested.connect(handle_context_menu) def create_ray_table(self, opt_model): osp = opt_model.optical_spec pupil = [0., 1.] fi = 0 wl = osp.spectral_region.reference_wvl fld, wvl, foc = osp.lookup_fld_wvl_focus(fi, wl) ray, ray_op, wvl = trace.trace_base(opt_model, pupil, fld, wvl) # ray, ray_op, wvl, opd = trace.trace_with_opd(opt_model, pupil, # fld, wvl, foc) # cr = trace.RayPkg(ray, ray_op, wvl) # s, t = trace.trace_coddington_fan(opt_model, cr, foc) ray = [RaySeg(*rs) for rs in ray] model = cmds.create_ray_table_model(opt_model, ray) self.create_table_view(model, "Ray Table") def create_table_view(self, table_model, table_title, close_callback=None): # construct the top level widget widget = QWidget() # construct the top level layout layout = QVBoxLayout(widget) table_view = TableView(table_model) table_view.setAlternatingRowColors(True) # Add table to box layout layout.addWidget(table_view) # set the layout on the widget widget.setLayout(layout) sub = self.add_subwindow(widget, ModelInfo(self.app_manager.model, cmds.update_table_view, (table_view,))) sub.setWindowTitle(table_title) sub.installEventFilter(self) table_view.setMinimumWidth(table_view.horizontalHeader().length() + table_view.horizontalHeader().height()) # The following line should work but returns 0 # table_view.verticalHeader().width()) view_width = table_view.width() view_ht = table_view.height() orig_x, orig_y = self.initial_window_offset() sub.setGeometry(orig_x, orig_y, view_width, view_ht) # table data updated successfully table_model.update.connect(self.on_data_changed) sub.show() return table_view def eventFilter(self, obj, event): """Used by table_view in response to installEventFilter.""" if (event.type() == QEvent.Close): print('close event received:', obj) return False def refresh_gui(self, **kwargs): self.app_manager.refresh_gui(**kwargs) def refresh_app_ui(self): dock.update_dock_windows(self) def handle_ideal_imager_command(self, iid, command, specsheet): ''' link Ideal Imager Dialog buttons to model actions iid: ideal imager dialog command: text field with the action - same as button label specsheet: the input specsheet used to drive the actions ''' if command == 'Apply': opt_model = self.app_manager.model opt_model.set_from_specsheet(specsheet) self.refresh_gui() elif command == 'Close': for view, info in self.app_manager.view_dict.items(): if iid == info[0]: self.delete_subwindow(view) view.close() break elif command == 'Update': opt_model = self.app_manager.model specsheet = opt_model.specsheet firstorder.specsheet_from_parax_data(opt_model, specsheet) iid.specsheet_dict[specsheet.conjugate_type] = specsheet iid.update_values() elif command == 'New': opt_model = cmds.create_new_optical_model_from_specsheet(specsheet) self.app_manager.set_model(opt_model) for view, info in self.app_manager.view_dict.items(): if iid == info[0]: w = iid mi = info[1] args = (iid, opt_model) new_mi = ModelInfo(model=opt_model, fct=mi.fct, args=args, kwargs=mi.kwargs) self.app_manager.view_dict[view] = w, new_mi self.refresh_gui() self.create_lens_table() cmds.create_live_layout_view(opt_model, gui_parent=self) cmds.create_paraxial_design_view_v2(opt_model, 'ht', gui_parent=self) self.refresh_gui() @pyqtSlot(object, int) def on_data_changed(self, rootObj, index): self.refresh_gui()
class MainWindow(QMainWindow): count = 0 def __init__(self, parent=None): super().__init__(parent) self.mdi = QMdiArea() self.setCentralWidget(self.mdi) self.app_manager = AppManager(None, gui_parent=self) self.mdi.subWindowActivated.connect(self.app_manager.on_view_activated) self.left = 100 self.top = 50 self.width = 1800 self.height = 1200 self.setGeometry(self.left, self.top, self.width, self.height) bar = self.menuBar() file = bar.addMenu("File") file.addAction("New") file.addAction("Open...") file.addSeparator() file.addAction("Save") file.addAction("Save As...") file.addAction("Close") file.triggered[QAction].connect(self.file_action) view = bar.addMenu("View") view.addAction("Spec Sheet") view.addAction("Optical Layout") view.addAction("Lens Table") view.addAction("Element Table") view.addAction("Lens View") view.addSeparator() view.addAction("Paraxial Model") view.addAction("Paraxial Height View") view.addAction("Paraxial Height View V2") view.addAction("Paraxial Slope View") view.addAction("Paraxial Ray Table") view.addAction("Ray Table") view.addSeparator() view.addAction("Ray Fans") view.addAction("OPD Fans") view.addAction("Spot Diagram") view.addAction("Wavefront Map") view.addAction("Astigmatism Curves") view.addAction("3rd Order Aberrations") view.addSeparator() view.triggered[QAction].connect(self.view_action) wnd = bar.addMenu("Window") wnd.addAction("Cascade") wnd.addAction("Tiled") wnd.addSeparator() dock.create_dock_windows(self) for pi in dock.panels.values(): wnd.addAction(pi.menu_action) wnd.triggered[QAction].connect(self.window_action) self.setWindowTitle("Ray Optics") self.show() self.new_model() self.add_ipython_subwindow() # pth = Path(__file__).resolve() # try: # root_pos = pth.parts.index('rayoptics') # except ValueError: # logging.debug("Can't find rayoptics: path is %s", pth) # else: # path = Path(*pth.parts[:root_pos+1]) # self.open_file(path / "codev/tests/asp46.seq") # self.open_file(path / "codev/tests/dar_test.seq") # self.open_file(path / "codev/tests/paraboloid.seq") # self.open_file(path / "codev/tests/paraboloid_f8.seq") # self.open_file(path / "codev/tests/schmidt.seq") # self.open_file(path / "codev/tests/questar35.seq") # self.open_file(path / "codev/tests/rc_f16.seq") # self.open_file(path / "codev/tests/ag_dblgauss.seq") # self.open_file(path / "codev/tests/threemir.seq") # self.open_file(path / "codev/tests/folded_lenses.seq") # self.open_file(path / "codev/tests/unfolded_lenses_w_ape.seq") # self.open_file(path / "codev/tests/lens_reflection_test.seq") # self.open_file(path / "codev/tests/dec_tilt_test.seq") # self.open_file(path / "codev/tests/landscape_lens.seq") # self.open_file(path / "codev/tests/mangin.seq") # self.open_file(path / "optical/tests/cell_phone_camera.roa") # self.open_file(path / "optical/tests/singlet_f3.roa") # try: # root_pos = pth.parts.index('ray-optics') # except ValueError: # logging.debug("Can't find ray-optics: path is %s", pth) # else: # path = Path(*pth.parts[:root_pos+1]) # self.open_file(path / "models/TwoMirror.roa") # self.open_file(path / "models/TwoSphericalMirror.roa") # self.open_file(path / "models/Sasian Triplet.roa") # self.open_file(path / "models/singlet_f5.roa") # self.open_file(path / "models/thinlens.roa") # self.open_file(path / "models/thin_triplet.roa") # self.open_file(path / "models/Cassegrain.roa") # self.open_file(path / "models/Ritchey_Chretien.roa") # finally: # self.add_ipython_subwindow() def add_subwindow(self, widget, model_info): sub_wind = self.mdi.addSubWindow(widget) self.app_manager.add_view(sub_wind, widget, model_info) MainWindow.count += 1 return sub_wind def delete_subwindow(self, sub_wind): self.app_manager.delete_view(sub_wind) self.mdi.removeSubWindow(sub_wind) MainWindow.count -= 1 def add_ipython_subwindow(self): try: create_ipython_console(self, 'iPython console', 600, 400) except MultipleInstanceError: logging.debug("Unable to open iPython console. " "MultipleInstanceError") except Exception as inst: print(type(inst)) # the exception instance print(inst.args) # arguments stored in .args print(inst) # __str__ allows args to be printed directly, pass # but may be overridden in exception subclasses def initial_window_offset(self): offset_x = 50 offset_y = 25 orig_x = (MainWindow.count - 1) * offset_x orig_y = (MainWindow.count - 1) * offset_y return orig_x, orig_y def file_action(self, q): if q.text() == "New": self.new_model() if q.text() == "Open...": options = QFileDialog.Options() # options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "CODE V Files (*.seq);;Ray-Optics Files (*.roa)", options=options) if fileName: logging.debug("open file: %s", fileName) self.open_file(fileName) if q.text() == "Save As...": options = QFileDialog.Options() # options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName( self, "QFileDialog.getSaveFileName()", "", "Ray-Optics Files (*.roa);;All Files (*)", options=options) if fileName: logging.debug("save file: %s", fileName) self.save_file(fileName) if q.text() == "Close": self.close_model() def new_model(self): iid = cmds.create_new_ideal_imager(gui_parent=self, conjugate_type='infinite') self.refresh_app_ui() def open_file(self, file_name): self.cur_filename = file_name self.app_manager.set_model(open_model(file_name)) self.is_changed = True self.create_lens_table() cmds.create_live_layout_view(self.app_manager.model, gui_parent=self) # cmds.create_lens_layout_view(self.app_manager.model, gui_parent=self) # self.create_2D_lens_view() self.refresh_app_ui() def save_file(self, file_name): self.app_manager.model.save_model(file_name) self.cur_filename = file_name self.is_changed = False def close_model(self): """ NOTE: this does not check to save a modified model """ self.app_manager.close_model(self.delete_subwindow) def view_action(self, q): opt_model = self.app_manager.model if q.text() == "Spec Sheet": cmds.create_new_ideal_imager(opt_model=opt_model, gui_parent=self) if q.text() == "Optical Layout": cmds.create_live_layout_view(opt_model, gui_parent=self) if q.text() == "Lens View": cmds.create_lens_layout_view(opt_model, gui_parent=self) # self.create_2D_lens_view() if q.text() == "Lens Table": self.create_lens_table() if q.text() == "Element Table": model = cmds.create_element_table_model(opt_model) self.create_table_view(model, "Element Table") if q.text() == "Ray Fans": cmds.create_ray_fan_view(opt_model, "Ray", gui_parent=self) if q.text() == "OPD Fans": cmds.create_ray_fan_view(opt_model, "OPD", gui_parent=self) if q.text() == "Spot Diagram": cmds.create_ray_grid_view(opt_model, gui_parent=self) if q.text() == "Wavefront Map": cmds.create_wavefront_view(opt_model, gui_parent=self) if q.text() == "Astigmatism Curves": cmds.create_field_curves(opt_model, gui_parent=self) if q.text() == "3rd Order Aberrations": cmds.create_3rd_order_bar_chart(opt_model, gui_parent=self) if q.text() == "Paraxial Height View": cmds.create_paraxial_design_view(opt_model, 'ht', gui_parent=self) if q.text() == "Paraxial Height View V2": cmds.create_paraxial_design_view_v2(opt_model, 'ht', gui_parent=self) if q.text() == "Paraxial Slope View": cmds.create_paraxial_design_view(opt_model, 'slp', gui_parent=self) if q.text() == "Paraxial Ray Table": model = cmds.create_parax_table_model(opt_model) self.create_table_view(model, "Paraxial Ray Table") if q.text() == "Paraxial Model": model = cmds.create_parax_model_table(opt_model) self.create_table_view(model, "Paraxial Model") if q.text() == "Ray Table": self.create_ray_table(opt_model) def window_action(self, q): if q.text() == "Cascade": self.mdi.cascadeSubWindows() if q.text() == "Tiled": self.mdi.tileSubWindows() def create_lens_table(self): seq_model = self.app_manager.model.seq_model model = cmds.create_lens_table_model(seq_model) self.create_table_view(model, "Surface Data Table") def create_ray_table(self, opt_model): osp = opt_model.optical_spec pupil = [0., 1.] fi = 0 wl = osp.spectral_region.reference_wvl fld, wvl, foc = osp.lookup_fld_wvl_focus(fi, wl) ray, ray_op, wvl = trace.trace_base(opt_model, pupil, fld, wvl) # ray, ray_op, wvl, opd = trace.trace_with_opd(opt_model, pupil, # fld, wvl, foc) # cr = trace.RayPkg(ray, ray_op, wvl) # s, t = trace.trace_coddington_fan(opt_model, cr, foc) ray = [RaySeg(*rs) for rs in ray] model = cmds.create_ray_table_model(opt_model, ray) self.create_table_view(model, "Ray Table") def create_2D_lens_view(self): scene2d = QGraphicsScene() self.create_element_model(scene2d) self.create_ray_model(scene2d) scene2d.setBackgroundBrush(QColor(237, 243, 254)) # light blue sceneRect2d = scene2d.sceneRect() # construct the top level widget widget = QWidget() # construct the top level layout layout = QVBoxLayout(widget) # set the layout on the widget widget.setLayout(layout) sub = self.add_subwindow( widget, ModelInfo(self.app_manager.model, MainWindow.update_2D_lens_view, (scene2d, ))) sub.setWindowTitle("2D Lens View") view_width = 660 view_ht = 440 view_ratio = view_width / view_ht orig_x, orig_y = self.initial_window_offset() sub.setGeometry(orig_x, orig_y, view_width, view_ht) self.gview2d = QGraphicsView(scene2d) scene_ratio = sceneRect2d.width() / sceneRect2d.height() oversize_fraction = 1.2 if scene_ratio > view_ratio: view_scale = view_width / (oversize_fraction * sceneRect2d.width()) else: view_scale = view_ht / (oversize_fraction * sceneRect2d.height()) self.gview2d.scale(view_scale, view_scale) layout.addWidget(self.gview2d) sub.show() return sub def update_2D_lens_view(scene2d): for gi in scene2d.items(): gi.prepareGeometryChange() gi.update_shape() def create_element_model(self, gscene): ele_model = self.app_manager.model.ele_model ele_model.elements_from_sequence(self.app_manager.model.seq_model) for e in ele_model.elements: ge = OpticalElement(e) gscene.addItem(ge) def create_ray_model(self, gscene, start_surf=1): opt_model = self.app_manager.model img_dist = abs(opt_model.optical_spec.parax_data[2].img_dist) start_offset = 0.05 * (gscene.sceneRect().width() + img_dist) fov = opt_model.optical_spec.field_of_view for fi, f in enumerate(fov.fields): rb = RayBundle(opt_model, fi, start_offset) gscene.addItem(rb) def create_table_view(self, table_model, table_title, close_callback=None): # construct the top level widget widget = QWidget() # construct the top level layout layout = QVBoxLayout(widget) tableView = QTableView() tableView.setAlternatingRowColors(True) # Add table to box layout layout.addWidget(tableView) # set the layout on the widget widget.setLayout(layout) sub = self.add_subwindow( widget, ModelInfo(self.app_manager.model, cmds.update_table_view, (tableView, ))) sub.setWindowTitle(table_title) sub.installEventFilter(self) tableView.setModel(table_model) tableView.setMinimumWidth(tableView.horizontalHeader().length() + tableView.horizontalHeader().height()) # The following line should work but returns 0 # tableView.verticalHeader().width()) view_width = tableView.width() view_ht = tableView.height() orig_x, orig_y = self.initial_window_offset() sub.setGeometry(orig_x, orig_y, view_width, view_ht) # table data updated successfully table_model.update.connect(self.on_data_changed) sub.show() return sub def eventFilter(self, obj, event): if (event.type() == QEvent.Close): print('close event received:', obj) return False def refresh_gui(self): self.app_manager.refresh_gui() def refresh_app_ui(self): dock.update_dock_windows(self) def handle_ideal_imager_command(self, iid, command, specsheet): if command == 'Apply': opt_model = self.app_manager.model opt_model.set_from_specsheet(specsheet) self.refresh_gui() elif command == 'Close': for view, info in self.app_manager.view_dict.items(): if iid == info[0]: view.close() elif command == 'Update': opt_model = self.app_manager.model specsheet = opt_model.specsheet firstorder.specsheet_from_parax_data(opt_model, specsheet) iid.specsheet_dict[specsheet.conjugate_type] = specsheet iid.update_values() elif command == 'New': opt_model = cmds.create_new_optical_model_from_specsheet(specsheet) self.app_manager.set_model(opt_model) for view, info in self.app_manager.view_dict.items(): if iid == info[0]: w = iid mi = info[1] args = (iid, opt_model) new_mi = ModelInfo(model=opt_model, fct=mi.fct, args=args, kwargs=mi.kwargs) self.app_manager.view_dict[view] = w, new_mi self.refresh_gui() self.create_lens_table() cmds.create_live_layout_view(opt_model, gui_parent=self) cmds.create_paraxial_design_view(opt_model, 'ht', gui_parent=self) self.refresh_gui() @pyqtSlot(object, int) def on_data_changed(self, rootObj, index): self.refresh_gui()
def __init__(self, parent=None): super().__init__(parent) self.mdi = QMdiArea() self.setCentralWidget(self.mdi) self.app_manager = AppManager(None, gui_parent=self) self.mdi.subWindowActivated.connect(self.app_manager.on_view_activated) self.left = 100 self.top = 50 self.width = 1800 self.height = 1200 self.setGeometry(self.left, self.top, self.width, self.height) bar = self.menuBar() file = bar.addMenu("File") file.addAction("New") file.addAction("Open...") file.addSeparator() file.addAction("Save") file.addAction("Save As...") file.addAction("Close") file.triggered[QAction].connect(self.file_action) view = bar.addMenu("View") view.addAction("Spec Sheet") view.addAction("Optical Layout") view.addAction("Lens Table") view.addAction("Element Table") view.addAction("Lens View") view.addSeparator() view.addAction("Paraxial Model") view.addAction("Paraxial Height View") view.addAction("Paraxial Height View V2") view.addAction("Paraxial Slope View") view.addAction("Paraxial Ray Table") view.addAction("Ray Table") view.addSeparator() view.addAction("Ray Fans") view.addAction("OPD Fans") view.addAction("Spot Diagram") view.addAction("Wavefront Map") view.addAction("Astigmatism Curves") view.addAction("3rd Order Aberrations") view.addSeparator() view.triggered[QAction].connect(self.view_action) wnd = bar.addMenu("Window") wnd.addAction("Cascade") wnd.addAction("Tiled") wnd.addSeparator() dock.create_dock_windows(self) for pi in dock.panels.values(): wnd.addAction(pi.menu_action) wnd.triggered[QAction].connect(self.window_action) self.setWindowTitle("Ray Optics") self.show() self.new_model() self.add_ipython_subwindow()
def __init__(self, parent=None, qtapp=None): super().__init__(parent) self.qtapp = qtapp self.mdi = QMdiArea() self.setCentralWidget(self.mdi) self.app_manager = AppManager(None, gui_parent=self) self.mdi.subWindowActivated.connect(self.app_manager.on_view_activated) self.is_dark = self.light_or_dark(False) self.left = 100 self.top = 50 self.width = 1800 self.height = 1200 self.setGeometry(self.left, self.top, self.width, self.height) bar = self.menuBar() file_menu = bar.addMenu("File") file_menu.addAction("New") file_menu.addAction("Open...") file_menu.addSeparator() file_menu.addAction("Save") file_menu.addAction("Save As...") file_menu.addAction("Close") file_menu.triggered[QAction].connect(self.file_action) view_menu = bar.addMenu("View") view_menu.addAction("Spec Sheet") view_menu.addAction("Optical Layout") view_menu.addAction("Lens Table") view_menu.addAction("Element Table") view_menu.addAction("Lens View") view_menu.triggered[QAction].connect(self.view_action) parax_menu = bar.addMenu("Paraxial Model") parax_menu.addAction("Paraxial Model") parax_menu.addAction("y-ybar View") parax_menu.addAction("nu-nubar View") parax_menu.addAction("yui Ray Table") parax_menu.addAction("3rd Order Aberrations") parax_menu.triggered[QAction].connect(self.view_action) analysis_menu = bar.addMenu("Analysis") view_menu.addAction("Ray Table") analysis_menu.addAction("Ray Fans") analysis_menu.addAction("OPD Fans") analysis_menu.addAction("Spot Diagram") analysis_menu.addAction("Wavefront Map") analysis_menu.addAction("Astigmatism Curves") analysis_menu.triggered[QAction].connect(self.view_action) wnd_menu = bar.addMenu("Window") wnd_menu.addAction("Cascade") wnd_menu.addAction("Tiled") wnd_menu.addSeparator() wnd_menu.addAction("Light UI") wnd_menu.addAction("Dark UI") wnd_menu.addSeparator() dock.create_dock_windows(self) for pi in dock.panels.values(): wnd_menu.addAction(pi.menu_action) wnd_menu.triggered[QAction].connect(self.window_action) self.setWindowTitle("Ray Optics") self.show() if True: # create new model self.new_model() self.add_ipython_subwindow() else: # restore a default model pth = Path(__file__).resolve() try: root_pos = pth.parts.index('rayoptics') except ValueError: logging.debug("Can't find rayoptics: path is %s", pth) else: path = Path(*pth.parts[:root_pos + 1]) # self.open_file(path / "codev/tests/asp46.seq") # self.open_file(path / "codev/tests/dar_test.seq") # self.open_file(path / "codev/tests/paraboloid.seq") # self.open_file(path / "codev/tests/paraboloid_f8.seq") # self.open_file(path / "codev/tests/schmidt.seq") # self.open_file(path / "codev/tests/questar35.seq") # self.open_file(path / "codev/tests/rc_f16.seq") # self.open_file(path / "codev/tests/ag_dblgauss.seq") # self.open_file(path / "codev/tests/threemir.seq") # self.open_file(path / "codev/tests/folded_lenses.seq") # self.open_file(path / "codev/tests/lens_reflection_test.seq") # self.open_file(path / "codev/tests/dec_tilt_test.seq") # self.open_file(path / "codev/tests/landscape_lens.seq") # self.open_file(path / "codev/tests/mangin.seq") # self.open_file(path / "optical/tests/cell_phone_camera.roa") # self.open_file(path / "optical/tests/singlet_f3.roa") # self.open_file(path / "models/Cassegrain.roa") # self.open_file(path / "models/collimator.roa") # self.open_file(path / "models/Dall-Kirkham.roa") # self.open_file(path / "models/petzval.roa") # self.open_file(path / "models/Ritchey_Chretien.roa") # self.open_file(path / "models/Sasian Triplet.roa") # self.open_file(path / "models/singlet_f5.roa") # self.open_file(path / "models/thinlens.roa") # self.open_file(path / "models/telephoto.roa") self.open_file(path / "models/thin_triplet.roa") # self.open_file(path / "models/TwoMirror.roa") # self.open_file(path / "models/TwoSphericalMirror.roa") finally: self.add_ipython_subwindow()