def save_data(self, filename=None): """Save data""" if filename is None: filename = self.filename if filename is None: filename = getcwd_or_home() filename, _selfilter = getsavefilename(self, _("Save data"), filename, iofunctions.save_filters) if filename: self.filename = filename else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() error_message = self.shellwidget.save_namespace(self.filename) self.shellwidget._kernel_reply = None QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: if 'Some objects could not be saved:' in error_message: save_data_message = ( _('<b>Some objects could not be saved:</b>') + '<br><br><code>{obj_list}</code>'.format( obj_list=error_message.split(': ')[1])) else: save_data_message = _( '<b>Unable to save current workspace</b>' '<br><br>Error message:<br>') + error_message QMessageBox.critical(self, _("Save data"), save_data_message) self.save_button.setEnabled(self.filename is not None)
def show_data(self, justanalyzed=False): if not justanalyzed: self.output = None self.log_button.setEnabled(self.output is not None and len(self.output) > 0) self.kill_if_running() filename = to_text_string(self.filecombo.currentText()) if not filename: return if self.stopped: self.datelabel.setText(_('Run stopped by user.')) self.datatree.initialize_view() return self.datelabel.setText(_('Sorting data, please wait...')) QApplication.processEvents() self.datatree.load_data(self.DATAPATH) self.datatree.show_tree() text_style = "<span style=\'color: %s\'><b>%s </b></span>" date_text = text_style % (self.text_color, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) self.datelabel.setText(date_text)
def set_splash(self, msg=None): if not self.splash: return if msg: self.splash.showMessage(msg, Qt.AlignBottom | Qt.AlignLeft | Qt.AlignAbsolute, QColor(Qt.black)) QApplication.processEvents(QEventLoop.AllEvents)
def save_data(self, filename=None): """Save data""" if filename is None: filename = self.filename if filename is None: filename = getcwd_or_home() filename, _selfilter = getsavefilename(self, _("Save data"), filename, iofunctions.save_filters) if filename: self.filename = filename else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() error_message = self.shellwidget.save_namespace(self.filename) self.shellwidget._kernel_reply = None QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical(self, _("Save data"), _("<b>Unable to save current workspace</b>" "<br><br>Error message:<br>%s") % error_message) self.save_button.setEnabled(self.filename is not None)
def ending_long_process(self, message=""): """ Clear main window's status bar and restore mouse cursor. """ QApplication.restoreOverrideCursor() self.show_message(message, timeout=2000) QApplication.processEvents()
def save_data(self, filename=None): """Save data""" if filename is None: filename = self.filename if filename is None: filename = getcwd() filename, _selfilter = getsavefilename(self, _("Save data"), filename, iofunctions.save_filters) if filename: self.filename = filename else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() if self.is_internal_shell: wsfilter = self.get_internal_shell_filter('picklable', check_all=True) namespace = wsfilter(self.shellwidget.interpreter.namespace).copy() error_message = iofunctions.save(namespace, filename) else: settings = self.get_view_settings() error_message = monitor_save_globals(self._get_sock(), settings, filename) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical(self, _("Save data"), _("<b>Unable to save current workspace</b>" "<br><br>Error message:<br>%s") % error_message) self.save_button.setEnabled(self.filename is not None)
def main(self): """ Main function to process input and call smoothing function """ success = self.input_validation() if not success: return self.hide() self.abort_window = AbortWindow(self) QApplication.processEvents() # Add smoothing parameters self.smooth_cube.abort_window = self.abort_window if self.smooth_cube.parent is None and self.parent is not self.smooth_cube: self.smooth_cube.parent = self.parent if self.parent is not self.smooth_cube: self.smooth_cube.data = self.data self.smooth_cube.smoothing_axis = self.current_axis self.smooth_cube.kernel_type = self.current_kernel_type if self.current_kernel_type == "median": self.smooth_cube.kernel_size = int(self.k_size.text()) else: self.smooth_cube.kernel_size = float(self.k_size.text()) self.smooth_cube.component_id = str(self.component_combo.currentText()) self.smooth_cube.output_as_component = True if self.is_preview_active: self.parent.end_smoothing_preview() self.is_preview_active = False self.smooth_cube.multi_threading_smooth() return
def __init__(self, parent=None, job_name='', script_to_run=None, thread_index=-1): self.parent = parent if self.parent.job_monitor_interface is None: job_ui = JobMonitorInterface(parent=self.parent) job_ui.show() QApplication.processEvents() self.parent.job_monitor_interface = job_ui job_ui.launch_logbook_thread() else: self.parent.job_monitor_interface.activateWindow() job_ui = self.parent.job_monitor_interface if job_name == '': return job_list = self.parent.job_list p = subprocess.Popen(script_to_run.split()) new_job = {'job_name': job_name, 'time': self.get_launch_time(), 'status': 'processing', 'pid': p.pid, 'subprocess': p} job_list.append(new_job) self.parent.job_list = job_list job_ui.refresh_table(job_list)
def starting_long_process(self, message): """ Showing message in main window's status bar and changing mouse cursor to Qt.WaitCursor """ self.__show_message(message) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents()
def run_script(self, script): with self.gui.wait_cursor(): self.set_output("") self.ui.labelLineNumber.setText("") QApplication.processEvents() sys.stdout = self starttime = -time.time() line_added=0 try: self.output = [] try: self.scriptRunner.run(script) except NameError as e: s = str(e).split("'") if len(s) == 3 and ((s[0] == "global name " and s[2] == " is not defined") or (s[0] == "name " and s[2] == " is not defined")): #python 3.5 lines = script.split("\n") if "# auto global" in lines[0] and s[1] in lines[0]: pass else: if self.gui.get_confirmation("Add global variable", "The variable '%s' seems to be missing in a scope. \nDo you want to add declare it as global?"%s[1])==True: if "# auto global" in lines[0] and s[1] not in lines[0].replace("# auto global","").replace("global",""): lines[0] = lines[0].replace(" # auto global", ", %s # auto global" % s[1]) else: lines[0] = "global %s # auto global\n%s" % (s[1], lines[0]) line_added = 1 script = "\n".join(lines) self.ui.tabWidget.currentWidget().set_script(script) raise self.set_output("".join(self.output)) beep(1000, 50) except (Warning, Exception) as inst: try: limit = -["exec(script_code, globals(), locals())" in traceback.format_exc(limit=-i) for i in range(100)].index(True)-1 except: limit=None traceback.print_exc(file=sys.stdout, limit=limit) self.set_output("".join(self.output)) sys.stdout = sys.__stdout__ try: linenr = self.output[[self.output.index(l) for l in self.output if "File \"<string>\", line " in l][-1]] linenr = linenr[23:] if "," in linenr: linenr = int(linenr[:linenr.index(",")]) else: linenr = int(linenr) self.selectLine(linenr - 1+line_added) except IndexError: pass print ('-' * 60) beep(500, 50) finally: sys.stdout = sys.__stdout__ self.ui.labelLineNumber.setText("Script executed in %d seconds" % (time.time() + starttime))
def write_error(self): if os.name == 'nt': #---This is apparently necessary only on Windows (not sure though): # emptying standard output buffer before writing error output self.process.setReadChannel(QProcess.StandardOutput) if self.process.waitForReadyRead(1): self.write_output() self.shell.write_error(self.get_stderr()) QApplication.processEvents()
def __next__(self): if self.n % self.update_every == 0: if self.allow_cancel and self.QtProgressInformation._progressDialog.wasCanceled(): raise CancelWarning() self.QtProgressInformation._progressDialog.setValue(self.n) QApplication.processEvents() self.n += 1 return next(self.generator)
def exec_long_guitask(self, text, task, *args, **kwargs): self.__show(text, False) QApplication.processEvents() task(*args, **kwargs) self.__hide() return self.taskThread.result
def test_deleted_on_close(self): ws = CreateSampleWorkspace() pres = SampleLogs(ws) self.assert_widget_created() pres.view.close() QApplication.processEvents() self.assert_no_toplevel_widgets()
def test_deletes_on_close(self): with MockWorkspaceWidget() as temp_widget: widget = SettingsPresenter(temp_widget) self.assert_widget_created() self.assert_widget_exists("GeneralSettings", expected_count=1) widget.view.close() QApplication.processEvents() self.assert_no_toplevel_widgets()
def _post_message(self, message, timeout=60000): """ Post a message to the main window status bar with a timeout in ms """ if self.editor_widget: try: statusbar = self.editor_widget.window().statusBar() statusbar.showMessage(message, timeout) QApplication.processEvents() except AttributeError: pass
def test_window_force_deleted_correctly(self): ws = CreateEmptyTableWorkspace() p = TableWorkspaceDisplay(ws) self.assert_widget_created() p.force_close() QApplication.processEvents() self.assertEqual(None, p.ads_observer) self.assert_widget_not_present("work") self.assert_no_toplevel_widgets()
def get_splash(): from qtpy.QtCore import Qt from qtpy.QtWidgets import QApplication, QSplashScreen from qtpy.QtGui import QColor, QPixmap splash_pix = QPixmap(os.path.join( os.path.dirname(__file__), 'images', 'splash.png')) splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint) splash.show() splash.showMessage("Initializing...", Qt.AlignBottom | Qt.AlignCenter | Qt.AlignAbsolute, QColor(Qt.white)) QApplication.processEvents() return splash
def __show(self, text, allow_cancel, max_value=0): if not hasattr(self, '_progressDialog'): raise Exception ("%s inheriting QtProgressInformation must call QtProgressInformation.__init__" % self.__class__.__name__) self._progressDialog.reset() #reset cancel flag self._progressDialog.setWindowTitle(text) self._progressDialog.setMaximum(max_value) cancel_text = (None, "Cancel")[allow_cancel] self._progressDialog.setCancelButtonText(cancel_text) self._progressDialog self._progressDialog.show() QApplication.processEvents()
def preview(self): success = self.verify_input() if not success: self.statusBar().showMessage("Please fill in all fields") return t = self.make_catalog_table() if t is None: raise Exception("Spectra files were not found.") fb = list(t['id']) if len(fb) == 0: return row = pick_item(t, fb, title='Preview', label='Pick a target:') if row is None: return # Make cutouts using info in catalog. self.statusBar().showMessage("Making cutouts") output_path = os.path.join(self.save_path, self.output_dir_format) fits_cutouts, success_counter, success_table = go_make_cutouts( QTable(row), self.img_path, "cutouts", output_file_format=self.output_file_format, output_dir_format=output_path, clobber=True, apply_rotation=True, report=self.report) hdu = fits_cutouts[0] self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1) self.progress_bar.reset() QApplication.processEvents() if hdu is None: raise Exception("Could not make cutout. Object " "may be out of the image's range.") if self.session is not None: iv = StandaloneImageViewer(hdu.data, parent=self.session.application) iv.setWindowFlags(iv.windowFlags() | Qt.Tool) iv.show() else: import matplotlib.pyplot as plt plt.imshow(hdu.data) plt.show()
def test_window_force_deleted_correctly(self): ws = CreateSampleWorkspace() LoadInstrument(ws, InstrumentName='MARI', RewriteSpectraMap=False) p = InstrumentViewPresenter(ws) self.assert_widget_created() p.force_close() QApplication.processEvents() self.assertEqual(None, p.ads_observer) self.assert_widget_not_present("instr") self.assert_no_toplevel_widgets()
def test_deleted_on_close(self): mock_mfp = MockMultiFileInterpreter() view = CodeEditorTabWidget(mock_mfp) self.assert_widget_created() view.close() QApplication.processEvents() self.assert_widget_not_present(CodeEditorTabWidget.__name__) # closing our local mock should leave the QApplication without any widgets mock_mfp.close() QApplication.processEvents() self.assert_no_toplevel_widgets()
def test_editor_widget_not_leaked(self): widget = MultiPythonFileInterpreter() self.assertEqual(1, widget.editor_count) widget.append_new_editor() self.assertEqual(2, widget.editor_count) widget.append_new_editor() self.assertEqual(3, widget.editor_count) widget.close_tab(0) QApplication.processEvents() self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 2) widget.close_tab(0) QApplication.processEvents() self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 1) widget.close_all() QApplication.processEvents() # there should be zero interpreters self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 0) # close the whole widget, this should delete everything from the QApplication widget.close() QApplication.processEvents() self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 0) self.assert_no_toplevel_widgets()
def test_window_deleted_correctly(self): ws = CreateSampleWorkspace() p = MatrixWorkspaceDisplay(ws) self.assert_widget_created() p.close(ws.name()) self.assert_widget_created() QApplication.processEvents() self.assertEqual(None, p.ads_observer) self.assert_widget_not_present("work") self.assert_no_toplevel_widgets()
def _open_script_in_editor(self, script): """ Open the passed script in the Workbench script editor :param script: String; Path to the script """ # Get number of lines with open(script) as f: num_lines = len(f.readlines()) self._open_script_in_editor_call(script) # Force program to process events QApplication.processEvents() self.recovery_presenter.connect_progress_bar_to_recovery_view() self.recovery_presenter.set_up_progress_bar(num_lines)
def test_deleted_on_close(self): ws = CreateMDHistoWorkspace(Dimensionality=3, Extents='-3,3,-10,10,-1,1', SignalInput=range(100), ErrorInput=range(100), NumberOfBins='5,5,4', Names='Dim1,Dim2,Dim3', Units='MomentumTransfer,EnergyTransfer,Angstrom', OutputWorkspace='ws_MD_2d') pres = SliceViewer(ws) self.assert_widget_created() pres.view.close() QApplication.processEvents() self.assert_no_toplevel_widgets()
def preview(self): success = self.verify_input() if not success: self.statusBar().showMessage("Please fill in all fields") return t = self.make_catalog_table() index = pick_item(range(len(t)) , t["id"].tolist(), title='Preview', label='Pick a target:') if index is None: return t = QTable(t[index]) programName, file_extension = os.path.splitext(self.img_path) programName = os.path.basename(programName) #Make cutouts using info in catalog. self.statusBar().showMessage("Making cutouts") fits_cutouts, success_counter, success_table = go_make_cutouts( t, self.img_path, programName, output_file_format=self.output_file_format, output_dir_format=self.output_dir_format, clobber=True, apply_rotation=True, ispreview=True, report=self.report) hdu = fits_cutouts[0] self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1) self.progress_bar.reset() QApplication.processEvents() if hdu is None: raise Exception("Could not make cutout. " "Object may be out of the image's range.") if self.session is not None: iv = StandaloneImageViewer(hdu.data) iv.setWindowFlags(iv.windowFlags() | Qt.Tool) iv.show() else: import matplotlib.pyplot as plt plt.imshow(hdu.data) plt.show()
def update_pb(self): """ This function is called in the worker thread to update the progress bar and checks if the local class variable abort_flag is active. If the abort button is clicked, the main thread will set abort_flag to True. The next time the worker thread calls this function, a custom exception is raised terminating the calculation. The exception is handled by the WorkerThread class. :raises: AbortException: terminating smoothing calculation """ if self.abort_flag: raise AbortException("Abort Calculation") self.pb_counter += 1 self.pb.setValue(self.pb_counter) QApplication.processEvents()
def test_editor_widget_doesnt_create_find_replace_unless_requested(self): widget = MultiPythonFileInterpreter() self.assertEqual(1, widget.editor_count) widget.append_new_editor() self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 2) self.assert_number_of_widgets_matching("Embedded", 0) widget.close_tab(1) QApplication.processEvents() # there will always be 1, because we never allow an empty editor widget self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 1) self.assert_number_of_widgets_matching("Embedded", 0) # close the whole widget, this should delete everything from the QApplication widget.close() QApplication.processEvents() self.assert_number_of_widgets_matching(".interpreter.PythonFileInterpreter", 0) self.assert_no_toplevel_widgets()
def show_data(self, justanalyzed=False): if not justanalyzed: self.output = None self.log_button.setEnabled(self.output is not None \ and len(self.output) > 0) self.kill_if_running() filename = to_text_string(self.filecombo.currentText()) if not filename: return self.datelabel.setText(_('Sorting data, please wait...')) QApplication.processEvents() self.datatree.load_data(self.DATAPATH) self.datatree.show_tree() text_style = "<span style=\'color: #444444\'><b>%s </b></span>" date_text = text_style % time.strftime("%d %b %Y %H:%M", time.localtime()) self.datelabel.setText(date_text)
def main(self): """ Main function that uses information provided by the user and in the headers of spectra files to construct a catalog and make cutouts. """ success = self.verify_input() if not success: self.statusBar().showMessage("Please fill in all fields") return self.start_button.setText("Abort") self.start_button.clicked.disconnect() self.start_button.clicked.connect(self.abort) self.statusBar().showMessage("Making a list of files") QApplication.processEvents() fb, target_names = self.get_file_base() if len(fb) == 0: return #Change working path to save path cwd = os.getcwd() os.chdir(self.save_path) self.statusBar().showMessage("Making catalog") programName = os.path.basename(fb[0]).split("_")[0] t, skipped = self.make_catalog_table(fb, target_names, programName) if t is None: raise Exception( "All input spectra files have bad WCS and/or headers.") #Make cutouts using info in catalog. self.statusBar().showMessage("Making cutouts") success_counter, success_table = self.make_cutouts(t, self.img_path, programName, clobber=True, apply_rotation=True) if self.kill: self.kill = False self.progress_bar.reset() self.statusBar().showMessage("Waiting for user input") return self.statusBar().showMessage("DONE!") #If some spectra files do not have a cutout, a list of their names will be saved to # 'skipped_cutout_files.txt' in the save dir as the MOSViz Table file. directory = self.output_dir_format.format(programName) output_path = os.path.abspath(os.path.join(self.save_path, directory)) #Give notice to user on status. string = "Cutouts were made for %s out of %s files\n\nSaved at: %s" % ( success_counter, len(fb), output_path) if success_counter != len(fb): self.write_skipped(t, success_table, skipped) string += "\n\nA list of spectra files" string += "without cutouts is saved in" string += "'skipped_cutout_files.txt'" string += "\n\nSaved at: %s" % os.path.join( self.save_path, "skipped_cutout_files.txt") info = QMessageBox.information(self, "Status:", string) #Change back dir. os.chdir(cwd) usr_ans = QMessageBox.question( self, '', "Would you like to load all generated cutouts into glue?", QMessageBox.Yes | QMessageBox.No) if usr_ans == QMessageBox.Yes: os.chdir(self.save_path) data = [] for i, flag in enumerate(success_table): if flag: path = self.output_dir_format.format(programName) this_id = t["id"][i] fname = os.path.join( path, self.output_file_format.format(this_id, programName)) data.append(load_data(fname)) self.session.data_collection.merge(*data, label="%s_Cutouts" % programName) os.chdir(cwd) if self.tableGen and self.TableGen is not None: self.TableGen.cutout_response(output_path, self.custom_save_path) self.close() return
# ----------------------------------------------------------------------------- # Splash screen # ----------------------------------------------------------------------------- # Importing resources loads the data in from workbench.app.resources import qCleanupResources # noqa atexit.register(qCleanupResources) SPLASH = QSplashScreen(QPixmap(':/images/MantidSplashScreen.png'), Qt.WindowStaysOnTopHint) SPLASH.show() SPLASH.showMessage("Starting...", Qt.AlignBottom | Qt.AlignLeft | Qt.AlignAbsolute, QColor(Qt.black)) # The event loop has not started - force event processing QApplication.processEvents(QEventLoop.AllEvents) # ----------------------------------------------------------------------------- # Utilities/Widgets # ----------------------------------------------------------------------------- from mantidqt.py3compat import qbytearray_to_str # noqa from mantidqt.utils.qt import add_actions, create_action # noqa from mantidqt.widgets.manageuserdirectories import ManageUserDirectories # noqa from workbench.config.main import CONF # noqa from workbench.external.mantid import prepare_mantid_env # noqa # ----------------------------------------------------------------------------- # MainWindow # -----------------------------------------------------------------------------
def setValue(self, value): self.qt_progress_bar.setValue(value) QApplication.processEvents()
def start_measurements(self): self.clear() if _utils.SIMPLE: if not self.update_block_name(): return False if not self.move_to_initial_position(): return False if not self.read_temperature(): return False if not self.read_mass(): return False if not self.configure_measurement(): return False self.ui.pbt_start_measurement.setEnabled(False) _QApplication.processEvents() if self.ui.chb_scan_parameter.isChecked(): if not self.scan_parameter_dialog.valid_scan: msg = _QCoreApplication.translate( '', 'Invalid scan configuration.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical( self, title, msg, _QMessageBox.Ok) return False else: try: scan_parameter = self.scan_parameter_dialog.scan_parameter scan_values = self.scan_parameter_dialog.scan_values prev_value = getattr(self.advanced_options, scan_parameter) for value in scan_values: self.change_advanced_options_param(scan_parameter, value) self.start_one_measurement(silent=True) self.change_advanced_options_param(scan_parameter, prev_value) except Exception: msg = _QCoreApplication.translate( '', 'Set of measurements failed.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical( self, title, msg, _QMessageBox.Ok) return False msg = _QCoreApplication.translate( '', 'End of measurement.') title = _QCoreApplication.translate('', 'Information') _QMessageBox.information( self, title, msg, _QMessageBox.Ok) elif self.ui.chb_find_trigger.isChecked(): try: self.global_config.measure_position_1 = True self.global_config.measure_position_2 = False encoder_res = self.advanced_options.integrator_encoder_resolution initial_guess = self.ui.sb_trigger_initial_guess.value() scan_parameter = 'integration_trigger' scan_interval = encoder_res/36 scan_npts = 5 scan_values = _np.linspace( int(initial_guess - scan_interval/2), int(initial_guess + scan_interval/2), scan_npts) % encoder_res scan_values = scan_values.astype(int) prev_value = getattr(self.advanced_options, scan_parameter) msg = _QCoreApplication.translate( '', 'Place the magnet in Position 1.') title = _QCoreApplication.translate('', 'Information') reply = _QMessageBox.information( self, title, msg, _QMessageBox.Ok, _QMessageBox.Cancel) if reply == _QMessageBox.Cancel: self.stop_measurement(silent=True) return False for value in scan_values: self.change_advanced_options_param(scan_parameter, value) self.start_one_measurement(silent=True) mx_list_1 = [mx for mx in self.mx_list] self.mx_list = [] self.my_list = [] self.mz_list = [] msg = _QCoreApplication.translate( '', 'Rotate the magnet 180 degress around the X axis.') title = _QCoreApplication.translate('', 'Information') reply = _QMessageBox.information( self, title, msg, _QMessageBox.Ok, _QMessageBox.Cancel) if reply == _QMessageBox.Cancel: self.change_advanced_options_param(scan_parameter, prev_value) self.stop_measurement(silent=True) return False for value in scan_values: self.change_advanced_options_param(scan_parameter, value) self.start_one_measurement(silent=True) mx_list_2 = [mx for mx in self.mx_list] self.change_advanced_options_param(scan_parameter, prev_value) self.find_trigger_dialog.show(scan_values, mx_list_1, mx_list_2) except Exception: msg = _QCoreApplication.translate( '', 'Find trigger measurement failed.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical( self, title, msg, _QMessageBox.Ok) return False else: if not self.start_one_measurement(): return False msg = _QCoreApplication.translate( '', 'End of measurement.') title = _QCoreApplication.translate('', 'Information') _QMessageBox.information( self, title, msg, _QMessageBox.Ok) try: if _utils.SIMPLE: self.ui.te_comments.setText('') except Exception: pass self.ui.pbt_start_measurement.setEnabled(True) _QApplication.processEvents() return True
def move_to_initial_position(self): try: if self.stop: return False if not _integrator.connected: msg = _QCoreApplication.translate( '', 'Integrator not connected.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical(self, title, msg, _QMessageBox.Ok) return False trigger = self.advanced_options.integration_trigger encoder_res = self.advanced_options.integrator_encoder_resolution motor_resolution = self.advanced_options.motor_resolution rotation_direction = self.advanced_options.motor_rotation_direction driver_address = self.advanced_options.motor_driver_address wait = 0.5 tol = encoder_res/10 _driver.stop_motor(driver_address) _time.sleep(wait) current_position = int(_integrator.read_encoder()) position = trigger if _np.abs(current_position - position) <= tol: return True diff = (current_position - position) if rotation_direction == '-': diff = diff*(-1) pulses = (encoder_res - diff) % encoder_res steps = int((pulses*motor_resolution)/encoder_res) if not self.configure_driver(steps): return False if self.stop: return False _driver.move_motor(driver_address) _time.sleep(wait) while not _driver.ready(driver_address) and not self.stop: _time.sleep(wait) _QApplication.processEvents() _time.sleep(wait) if self.stop: return False return True except Exception: msg = _QCoreApplication.translate( '', 'Failed to move motor to initial position.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical(self, title, msg, _QMessageBox.Ok) _traceback.print_exc(file=_sys.stdout) return False
def make_cutouts(self, table, imagename, image_label, apply_rotation=False, image_ext=0, clobber=False, verbose=True, ispreview=False): """ This function is a modified copy of astroimtools.cutout_tools.make_cutouts. Make cutouts from a 2D image and write them to FITS files. Catalog must have the following columns with unit info, where applicable: * ``'id'`` - ID string; no unit necessary. * ``'ra'`` - RA (e.g., in degrees). * ``'dec'`` - DEC (e.g., in degrees). * ``'cutout_x_size'`` - Cutout width (e.g., in arcsec). * ``'cutout_y_size'`` - Cutout height (e.g., in arcsec). * ``'cutout_pa'`` - Cutout angle (e.g., in degrees). This is only use if user chooses to rotate the cutouts. Positive value will result in a clockwise rotation. * ``'spatial_pixel_scale'`` - Pixel scale (e.g., in arcsec/pix). The following are no longer used, so they are now optional: * ``'slit_pa'`` - Slit angle (e.g., in degrees). * ``'slit_width'`` - Slit width (e.g., in arcsec). * ``'slit_length'`` - Slit length (e.g., in arcsec). Cutouts are organized as follows:: working_dir/ <image_label>_cutouts/ <id>_<image_label>_cutout.fits Each cutout image is a simple single-extension FITS with updated WCS. Its header has the following special keywords: * ``OBJ_RA`` - RA of the cutout object in degrees. * ``OBJ_DEC`` - DEC of the cutout object in degrees. * ``OBJ_ROT`` - Rotation of cutout object in degrees. Can add Qt.WindowStaysOnTopHint to supper to keep window ontop. Parameters ---------- table : QTable Catalog table defining the sources to cut out. imagename : str Image to cut. image_label : str Label to name the cutout sub-directory and filenames. apply_rotation : bool Cutout will be rotated to a given angle. Default is `False`. image_ext : int, optional Image extension to extract header and data. Default is 0. clobber : bool, optional Overwrite existing files. Default is `False`. verbose : bool, optional Print extra info. Default is `True`. """ """ Now libs: """ # Optional dependencies... from reproject import reproject_interp with fits.open(imagename) as pf: data = pf[image_ext].data wcs = WCS(pf[image_ext].header) # It is more efficient to operate on an entire column at once. c = SkyCoord(table['ra'], table['dec']) x = (table['cutout_x_size'] / table['spatial_pixel_scale']).value # pix y = (table['cutout_y_size'] / table['spatial_pixel_scale']).value # pix pscl = table['spatial_pixel_scale'].to(u.deg / u.pix) # Do not rotate if column is missing. if 'cutout_pa' not in table.colnames: apply_rotation = False # Sub-directory, relative to working directory. path = self.output_dir_format.format(image_label) if not os.path.exists(path): os.mkdir(path) cutcls = partial(Cutout2D, data, wcs=wcs, mode='partial') if self.progress_bar is not None: self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(len(table) - 1) self.progress_bar.reset() counter = 0 success_counter = 0 success_table = [False for x in range(len(table['id']))] for position, x_pix, y_pix, pix_scl, row in zip(c, x, y, pscl, table): if self.kill: return None, None counter += 1 if self.status_bar is not None: self.status_bar().showMessage("Making cutouts (%s/%s)" % (counter, len(success_table))) if self.progress_bar is not None: self.progress_bar.setValue(counter) QApplication.processEvents() if apply_rotation: pix_rot = row['cutout_pa'].to(u.degree).value cutout_wcs = WCS(naxis=2) cutout_wcs.wcs.ctype = ['RA---TAN', 'DEC--TAN'] cutout_wcs.wcs.crval = [position.ra.deg, position.dec.deg] cutout_wcs.wcs.crpix = [(x_pix - 1) * 0.5, (y_pix - 1) * 0.5] try: cutout_wcs.wcs.cd = wcs.wcs.cd cutout_wcs.rotateCD(-pix_rot) except AttributeError: cutout_wcs.wcs.cdelt = wcs.wcs.cdelt cutout_wcs.wcs.crota = [0, -pix_rot] cutout_hdr = cutout_wcs.to_header() try: cutout_arr = reproject_interp((data, wcs), cutout_hdr, shape_out=(y_pix, x_pix), order=2) except Exception: if verbose: log.info('reproject failed: ' 'Skipping {0}'.format(row['id'])) continue cutout_arr = cutout_arr[0] # Ignore footprint cutout_hdr['OBJ_ROT'] = (pix_rot, 'Cutout rotation in degrees') else: try: cutout = cutcls(position, size=(y_pix, x_pix)) except NoConvergence: if verbose: log.info('WCS solution did not converge: ' 'Skipping {0}'.format(row['id'])) continue except NoOverlapError: if verbose: log.info('Cutout is not on image: ' 'Skipping {0}'.format(row['id'])) continue else: cutout_hdr = cutout.wcs.to_header() cutout_arr = cutout.data if np.array_equiv(cutout_arr, 0): if verbose: log.info('No data in cutout: Skipping {0}'.format( row['id'])) continue fname = os.path.join( path, self.output_file_format.format(row['id'], image_label)) # Construct FITS HDU. hdu = fits.PrimaryHDU(cutout_arr) hdu.header.update(cutout_hdr) hdu.header['OBJ_RA'] = (position.ra.deg, 'Cutout object RA in deg') hdu.header['OBJ_DEC'] = (position.dec.deg, 'Cutout object DEC in deg') if ispreview: return hdu else: hdu.writeto(fname, overwrite=clobber) success_counter += 1 success_table[counter - 1] = True if verbose: log.info('Wrote {0}'.format(fname)) self.progressBar.setValue(counter) QApplication.processEvents() if ispreview: return None else: return success_counter, success_table
def make_napari_viewer(qtbot, request: 'FixtureRequest', napari_plugin_manager): """A fixture function that creates a napari viewer for use in testing. Use this fixture as a function in your tests: viewer = make_napari_viewer() It accepts all the same arguments as napari.Viewer, plus the following test-related paramaters: ViewerClass : Type[napari.Viewer], optional Override the viewer class being used. By default, will use napari.viewer.Viewer strict_qt : bool or str, optional If True, a check will be performed after test cleanup to make sure that no top level widgets were created and *not* cleaned up during the test. If the string "raise" is provided, an AssertionError will be raised. Otherwise a warning is emitted. By default, this is False unless the test is being performed within the napari package. This can be made globally true by setting the 'NAPARI_STRICT_QT' environment variable. block_plugin_discovery : bool, optional Block discovery of non-builtin plugins. Note: plugins can still be manually registered by using the 'napari_plugin_manager' fixture and the `napari_plugin_manager.register()` method. By default, True. Examples -------- >>> def test_adding_shapes(make_napari_viewer): ... viewer = make_napari_viewer() ... viewer.add_shapes() ... assert len(viewer.layers) == 1 >>> def test_something_with_plugins(make_napari_viewer): ... viewer = make_napari_viewer(block_plugin_discovery=False) >>> def test_something_with_strict_qt_tests(make_napari_viewer): ... viewer = make_napari_viewer(strict_qt=True) """ from qtpy.QtWidgets import QApplication from napari import Viewer from napari._qt.qt_viewer import QtViewer from napari.settings import get_settings global GCPASS GCPASS += 1 if GCPASS % 50 == 0: gc.collect() else: gc.collect(1) _do_not_inline_below = len(QtViewer._instances) # # do not inline to avoid pytest trying to compute repr of expression. # # it fails if C++ object gone but not Python object. if request.config.getoption(_SAVE_GRAPH_OPNAME): fail_obj_graph(QtViewer) QtViewer._instances.clear() assert _do_not_inline_below == 0, ( "Some instance of QtViewer is not properly cleaned in one of previous test. For easier debug one may " f"use {_SAVE_GRAPH_OPNAME} flag for pytest to get graph of leaked objects. If you use qtbot (from pytest-qt)" " to clean Qt objects after test you may need to switch to manual clean using " "`deleteLater()` and `qtbot.wait(50)` later.") settings = get_settings() settings.reset() viewers: WeakSet[Viewer] = WeakSet() # may be overridden by using `make_napari_viewer(strict=True)` _strict = False initial = QApplication.topLevelWidgets() prior_exception = getattr(sys, 'last_value', None) is_internal_test = request.module.__name__.startswith("napari.") def actual_factory( *model_args, ViewerClass=Viewer, strict_qt=is_internal_test or os.getenv("NAPARI_STRICT_QT"), block_plugin_discovery=True, **model_kwargs, ): nonlocal _strict _strict = strict_qt if not block_plugin_discovery: napari_plugin_manager.discovery_blocker.stop() should_show = request.config.getoption("--show-napari-viewer") model_kwargs['show'] = model_kwargs.pop('show', should_show) viewer = ViewerClass(*model_args, **model_kwargs) viewers.add(viewer) return viewer yield actual_factory # Some tests might have the viewer closed, so this call will not be able # to access the window. with suppress(AttributeError): get_settings().reset() # close viewers, but don't saving window settings while closing for viewer in viewers: if hasattr(viewer.window, '_qt_window'): with patch.object(viewer.window._qt_window, '_save_current_window_settings'): viewer.close() else: viewer.close() if GCPASS % 50 == 0 or len(QtViewer._instances): gc.collect() else: gc.collect(1) if request.config.getoption(_SAVE_GRAPH_OPNAME): fail_obj_graph(QtViewer) _do_not_inline_below = len(QtViewer._instances) # do not inline to avoid pytest trying to compute repr of expression. # it fails if C++ object gone but not Python object. assert _do_not_inline_below == 0 # only check for leaked widgets if an exception was raised during the test, # or "strict" mode was used. if _strict and getattr(sys, 'last_value', None) is prior_exception: QApplication.processEvents() leak = set(QApplication.topLevelWidgets()).difference(initial) # still not sure how to clean up some of the remaining vispy # vispy.app.backends._qt.CanvasBackendDesktop widgets... if any([n.__class__.__name__ != 'CanvasBackendDesktop' for n in leak]): # just a warning... but this can be converted to test errors # in pytest with `-W error` msg = f"""The following Widgets leaked!: {leak}. Note: If other tests are failing it is likely that widgets will leak as they will be (indirectly) attached to the tracebacks of previous failures. Please only consider this an error if all other tests are passing. """ # Explanation notes on the above: While we are indeed looking at the # difference in sets of widgets between before and after, new object can # still not be garbage collected because of it. # in particular with VisPyCanvas, it looks like if a traceback keeps # contains the type, then instances are still attached to the type. # I'm not too sure why this is the case though. if _strict == 'raise': raise AssertionError(msg) else: warnings.warn(msg)
def setDescription(self, value): if not value.endswith(': '): value = f'{value}: ' self.description_label.setText(value) QApplication.processEvents()
def measure_position(self, gain): try: if self.stop: return False self.integrated_voltage = [] steps = int((self.advanced_options.integration_nr_turns + 1)*( self.advanced_options.motor_resolution)) if not self.configure_integrator(gain): return False if not self.configure_driver(steps): return False driver_address = self.advanced_options.motor_driver_address nr_turns = self.advanced_options.integration_nr_turns integration_points = self.advanced_options.integration_points total_npts = nr_turns*integration_points if total_npts > 100: step_status = int(total_npts/20) elif total_npts > 50: step_status = int(total_npts/10) else: step_status = 1 if not _integrator.start_measurement(): msg = _QCoreApplication.translate( '', 'Incorrect integrator status.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical( self, title, msg, _QMessageBox.Ok) return False if self.stop: return False _driver.move_motor(driver_address) self.ui.pgb_status.setMinimum(0) self.ui.pgb_status.setMaximum(total_npts) self.ui.pgb_status.setValue(0) count = 0 while (count < total_npts) and (not self.stop): _QApplication.processEvents() count = _integrator.get_data_count() if count % step_status == 0: self.ui.pgb_status.setValue(count) data = _integrator.get_data_array() if any(_np.isnan(di) for di in data): msg = _QCoreApplication.translate( '', ( 'Integrator over-range.\n' + 'Please configure a lower gain.' )) title = _QCoreApplication.translate('', 'Warning') _QMessageBox.warning(self, title, msg, _QMessageBox.Ok) return False if self.stop: return False _driver.stop_motor(driver_address) self.ui.pgb_status.setValue(total_npts) integrated_voltage = _np.array(data).reshape( nr_turns, integration_points).transpose() if nr_turns > 5: integrated_voltage = integrated_voltage[:, 1:-1] self.integrated_voltage = integrated_voltage*( _integrator.conversion_factor) if self.stop: return False return True except Exception: _traceback.print_exc(file=_sys.stdout) _driver.stop_motor( self.advanced_options.motor_driver_address) self.ui.pgb_status.setValue(0) msg = _QCoreApplication.translate( '', 'Measurement failed.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical(self, title, msg, _QMessageBox.Ok) return False
def main(self): """ Main metod that will take input from the user, make a MOSViz Table and save it to a file. It will use the information in the headers of the spectra files to fill in rows of the table. If the user has cutout, it will look for an image file with the corresponding object name and add it to the Table. """ success = self.verify_input() if not success: self.statusBar().showMessage("Input error") return self.generate_table_button.setDisabled(True) self.statusBar().showMessage("Making a list of files") target_names = [] fb = [] # File Base skipped = [] #List of files skipped. searchPath = os.path.join(self.spec_path,"*s2d.fits") for fn in glob(searchPath): name = os.path.basename(fn) name = name.split("_") #Split up file name if len(name) != 5: skipped.append([fn,"File name format not compliant."]) continue name = name[-4] # Get the target name from file target_names.append(name) fb.append(fn) #If no files are found, return if len(fb) == 0: self.statusBar().showMessage("NIRSpec files not found") self.generate_table_button.setDisabled(False) info = QMessageBox.information(self, "Status", "No NIRSpec files found in this directory\n" "File Name Format:\n\n" "<programName>_<objectName>_<instrument_filter>_ <grating>_<s2d|x1d>.fits") return fb = natural_sort(fb) #Change working path to save path cwd = os.getcwd() os.chdir(self.save_file_dir) self.statusBar().showMessage("Making catalog") QApplication.processEvents() #Setup local catalog. catalog = [] IDList = {} #Counter for objects with the same ID #Extract info from spectra files and save to catalog. projectName = os.path.basename(fb[0]).split("_")[0] for idx, fn in enumerate(fb): #For file name in file base: row = [] #Catch file error or load WCS: filex1d = fn.replace("s2d.fits", "x1d.fits") if os.path.isfile(filex1d): try: headx1d = fits.open(filex1d)['extract1d'].header wcs = WCS(headx1d) w1, w2 = wcs.wcs_pix2world(0., 0., 1) w1 = w1.tolist() w2 = w2.tolist() except Exception as e: print("WCS Read Failed:",e,":",filex1d) skipped.append([filex1d,str(e)]) continue else: skipped.append([fn,"x1d counterpart not found."]) continue try: head = fits.getheader(fn) except Exception as e: print("Header Read Failed:",e,":",fn) skipped.append([fn,str(e)]) continue #Make row for catalog: ID = target_names[idx] ID, IDList = unique_id(ID, IDList) if self.add_cutout_radio.isChecked(): cutout = self.get_cutout(fn, ID) else: cutout = "None" if self.abs_path or self.custom_save_path: spectrum1d = os.path.abspath(fn.replace("s2d.fits", "x1d.fits")) spectrum2d = os.path.abspath(fn) else: spectrum1d = os.path.join(".",os.path.basename(fn).replace("s2d.fits", "x1d.fits")) spectrum2d = os.path.join(".",os.path.basename(fn)) row.append(ID) #id row.append(w1) #ra row.append(w2) #dec row.append(spectrum1d) #spectrum1d row.append(spectrum2d) #spectrum2d row.append(cutout) #cutout row.append(0.2) #slit_width row.append(3.3) #slit_length row.append(head["CDELT2"]) #pix_scale (spatial_pixel_scale) row.append(head["PA_APER"]) #slit_pa catalog.append(row) #Add row to catalog #Write Skipped Files searchPath = os.path.join(self.spec_path,"*x1d.fits") for fn in glob(searchPath): name = os.path.basename(fn) name = name.split("_") #Split up file name if len(name) != 5: skipped.append([fn,"File name format not compliant."]) continue files2d = fn.replace("x1d.fits", "s2d.fits") if not os.path.isfile(files2d): skipped.append([fn,"s2d counterpart not found"]) if len(skipped) > 0: self._write_skipped(skipped) #if all spectra files were skipped if len(catalog) == 0: info = QMessageBox.critical(self, "Error", "MOSViz Table not generated: " "All spectra files were skipped.") os.chdir(cwd) self.close() return #Make and write MOSViz table self.statusBar().showMessage("Making MOSViz catalog") colNames = ["id","ra","dec","spectrum1d","spectrum2d","cutout", "slit_width","slit_length","spatial_pixel_scale","slit_pa"] t = QTable(rows=catalog, names=colNames) t["ra"].unit = u.deg t["dec"].unit = u.deg t["slit_width"].unit = u.arcsec t["slit_length"].unit = u.arcsec t["spatial_pixel_scale"].unit = (u.arcsec/u.pix) t["slit_pa"].unit = u.deg self.statusBar().showMessage("Saving MOSViz catalog") #Write MOSViz Table to file. t.write(self.save_file_name, format="ascii.ecsv", overwrite=True) #Change back dir. self.statusBar().showMessage("DONE!") os.chdir(cwd) moscatalogname = os.path.abspath(os.path.join(self.save_file_dir,self.save_file_name)) info = QMessageBox.information(self, "Status", "Catalog saved at:\n"+moscatalogname) self.close() return
def run_Import(self, action): """Prompt user to load a COMBINE archive or SED-ML file and translates it""" if action == 'c2p' or action == 'c2pwp' or action == 's2p' or action == 's2pwp': editorwindow = None #Used in editor.load processevents = True #Used in editor.load goto = None word = '' editor = self.main.editor editor0 = editor.get_current_editor() if editor0 is not None: position0 = editor0.get_position('cursor') filename0 = editor.get_current_filename() else: position0, filename0 = None, None # Recent files action raction = editor.sender() if isinstance(raction, QAction): filenames = from_qvariant(raction.data(), to_text_string) if not filenames: basedir = getcwd() if editor.edit_filetypes is None: editor.edit_filetypes = get_edit_filetypes() if editor.edit_filters is None: editor.edit_filters = get_edit_filters() c_fname = editor.get_current_filename() if c_fname is not None and c_fname != editor.TEMPFILE_PATH: basedir = os.path.dirname(c_fname) editor.redirect_stdio.emit(False) parent_widget = editor.get_current_editorstack() if filename0 is not None: selectedfilter = get_filter(editor.edit_filetypes, os.path.splitext(filename0)[1]) else: selectedfilter = '' if action == 'c2p' or action == 'c2pwp': filters = 'Combine archives (*.zip *.omex);;All files (*.*)' filenames, _selfilter = getopenfilenames( parent_widget, _("Open combine archive"), basedir, filters, selectedfilter=selectedfilter) else: filters = 'SED-ML files (*.sedml *.xml);;All files (*.*)' filenames, _selfilter = getopenfilenames( parent_widget, _("Open SED-ML file"), basedir, filters, selectedfilter=selectedfilter) editor.redirect_stdio.emit(True) if filenames: filenames = [ os.path.normpath(fname) for fname in filenames ] else: return focus_widget = QApplication.focusWidget() if editor.dockwidget and\ (not editor.dockwidget.isAncestorOf(focus_widget)\ and not isinstance(focus_widget, CodeEditor)): editor.dockwidget.setVisible(True) editor.dockwidget.setFocus() editor.dockwidget.raise_() def _convert(fname): fname = os.path.abspath(encoding.to_unicode_from_fs(fname)) if os.name == 'nt' and len(fname) >= 2 and fname[1] == ':': fname = fname[0].upper() + fname[1:] return fname if hasattr(filenames, 'replaceInStrings'): # This is a QStringList instance (PyQt API #1), converting to list: filenames = list(filenames) if not isinstance(filenames, list): filenames = [_convert(filenames)] else: filenames = [_convert(fname) for fname in list(filenames)] if isinstance(goto, int): goto = [goto] elif goto is not None and len(goto) != len(filenames): goto = None for index, filename in enumerate(filenames): if action == 'c2p' or action == 'c2pwp': p = re.compile('(.zip$|.omex$)') pythonfile = p.sub('.py', filename) if (pythonfile == filename): pythonfile = filename + ".py" else: p = re.compile('(.xml$|.sedml$)') if action == 's2p': pythonfile = p.sub('_sedml.py', filename) if (pythonfile == filename): pythonfile = filename + "_sedml.py" else: pythonfile = p.sub('_phrasedml.py', filename) if (pythonfile == filename): pythonfile = filename + "_phrasedml.py" current_editor = editor.set_current_filename( pythonfile, editorwindow) if current_editor is None: # -- Not a valid filename: if not os.path.isfile(filename): continue # -- current_es = editor.get_current_editorstack(editorwindow) # Creating the editor widget in the first editorstack (the one # that can't be destroyed), then cloning this editor widget in # all other editorstacks: finfo, newname = self.load_and_translate( filename, pythonfile, editor, action) finfo.path = editor.main.get_spyder_pythonpath() editor._clone_file_everywhere(finfo) current_editor = current_es.set_current_filename(newname) current_es.analyze_script() if goto is not None: # 'word' is assumed to be None as well current_editor.go_to_line(goto[index], word=word) position = current_editor.get_position('cursor') editor.cursor_moved(filename0, position0, filename, position) if (current_editor is not None): current_editor.clearFocus() current_editor.setFocus() current_editor.window().raise_() if processevents: QApplication.processEvents()
def xcsw_is_visible(self, state): if state: QApplication.processEvents() self.adjust_ycsw_height() else: self.adjust_ycsw_height(0)
def adjust_ycsw_height(self, height=None): if height is None: height = self.xcsw.height() - self.ycsw.toolbar.height() self.ycsw.adjust_height(height) if height: QApplication.processEvents()
def initialize(self): """Start pydoc server""" QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.start_server()
def main(): #========================================================================== # Proper high DPI scaling is available in Qt >= 5.6.0. This attribute must # be set before creating the application. #========================================================================== env = os.environ.copy() if CONF.get('main', 'high_dpi_custom_scale_factor'): factors = str(CONF.get('main', 'high_dpi_custom_scale_factors')) f = list(filter(None, factors.split(';'))) if len(f) == 1: env['QT_SCALE_FACTOR'] = f[0] else: env['QT_SCREEN_SCALE_FACTORS'] = factors else: env['QT_SCALE_FACTOR'] = '' env['QT_SCREEN_SCALE_FACTORS'] = '' # Splash screen # ------------------------------------------------------------------------- # Start Qt Splash to inform the user of the current status app = qapplication() restarter = Restarter() APP_ICON = QIcon(get_image_path("spyder")) app.setWindowIcon(APP_ICON) restarter.set_splash_message(_('Closing Spyder')) # Get variables spyder_args = env.pop('SPYDER_ARGS', None) pid = env.pop('SPYDER_PID', None) is_bootstrap = env.pop('SPYDER_IS_BOOTSTRAP', None) reset = env.pop('SPYDER_RESET', 'False') # Get the spyder base folder based on this file spyder_dir = osp.dirname(osp.dirname(osp.dirname(osp.abspath(__file__)))) if not any([spyder_args, pid, is_bootstrap, reset]): error = "This script can only be called from within a Spyder instance" raise RuntimeError(error) # Variables were stored as string literals in the environment, so to use # them we need to parse them in a safe manner. is_bootstrap = ast.literal_eval(is_bootstrap) pid = ast.literal_eval(pid) args = ast.literal_eval(spyder_args) reset = ast.literal_eval(reset) # SPYDER_DEBUG takes presedence over SPYDER_ARGS if '--debug' in args: args.remove('--debug') for level in ['minimal', 'verbose']: arg = f'--debug-info={level}' if arg in args: args.remove(arg) # Enforce the --new-instance flag when running spyder if '--new-instance' not in args: if is_bootstrap and '--' not in args: args = args + ['--', '--new-instance'] else: args.append('--new-instance') # Create the arguments needed for resetting if '--' in args: args_reset = ['--', '--reset'] else: args_reset = ['--reset'] # Build the base command if running_in_mac_app(sys.executable): exe = env['EXECUTABLEPATH'] command = [f'"{exe}"'] else: if is_bootstrap: script = osp.join(spyder_dir, 'bootstrap.py') else: script = osp.join(spyder_dir, 'spyder', 'app', 'start.py') command = [f'"{sys.executable}"', f'"{script}"'] # Adjust the command and/or arguments to subprocess depending on the OS shell = not IS_WINDOWS # Before launching a new Spyder instance we need to make sure that the # previous one has closed. We wait for a fixed and "reasonable" amount of # time and check, otherwise an error is launched wait_time = 90 if IS_WINDOWS else 30 # Seconds for counter in range(int(wait_time / SLEEP_TIME)): if not is_pid_running(pid): break time.sleep(SLEEP_TIME) # Throttling control QApplication.processEvents() # Needed to refresh the splash else: # The old spyder instance took too long to close and restart aborts restarter.launch_error_message(error_type=CLOSE_ERROR) # Reset Spyder (if required) # ------------------------------------------------------------------------- if reset: restarter.set_splash_message(_('Resetting Spyder to defaults')) try: p = subprocess.Popen(' '.join(command + args_reset), shell=shell, env=env) except Exception as error: restarter.launch_error_message(error_type=RESET_ERROR, error=error) else: p.communicate() pid_reset = p.pid # Before launching a new Spyder instance we need to make sure that the # reset subprocess has closed. We wait for a fixed and "reasonable" # amount of time and check, otherwise an error is launched. wait_time = 20 # Seconds for counter in range(int(wait_time / SLEEP_TIME)): if not is_pid_running(pid_reset): break time.sleep(SLEEP_TIME) # Throttling control QApplication.processEvents() # Needed to refresh the splash else: # The reset subprocess took too long and it is killed try: p.kill() except OSError as error: restarter.launch_error_message(error_type=RESET_ERROR, error=error) else: restarter.launch_error_message(error_type=RESET_ERROR) # Restart # ------------------------------------------------------------------------- restarter.set_splash_message(_('Restarting')) try: subprocess.Popen(' '.join(command + args), shell=shell, env=env) except Exception as error: restarter.launch_error_message(error_type=RESTART_ERROR, error=error)
def main(): # Splash screen # ------------------------------------------------------------------------- # Start Qt Splash to inform the user of the current status app = qapplication() restarter = Restarter() resample = not IS_WINDOWS # Resampling SVG icon only on non-Windows platforms (see Issue 1314): icon = ima.icon('spyder', resample=resample) app.setWindowIcon(icon) restarter.set_splash_message(_('Closing Spyder')) # Get variables # Note: Variables defined in app/spyder.py 'restart()' method spyder_args = os.environ.pop('SPYDER_ARGS', None) pid = os.environ.pop('SPYDER_PID', None) is_bootstrap = os.environ.pop('SPYDER_IS_BOOTSTRAP', None) reset = os.environ.pop('SPYDER_RESET', None) # Get the spyder base folder based on this file this_folder = osp.split(osp.dirname(osp.abspath(__file__)))[0] spyder_folder = osp.split(this_folder)[0] if not any([spyder_args, pid, is_bootstrap, reset]): error = "This script can only be called from within a Spyder instance" raise RuntimeError(error) # Variables were stored as string literals in the environment, so to use # them we need to parse them in a safe manner. is_bootstrap = ast.literal_eval(is_bootstrap) pid = ast.literal_eval(pid) args = ast.literal_eval(spyder_args) reset = ast.literal_eval(reset) # Enforce the --new-instance flag when running spyder if '--new-instance' not in args: if is_bootstrap and '--' not in args: args = args + ['--', '--new-instance'] else: args.append('--new-instance') # Create the arguments needed for reseting if '--' in args: args_reset = ['--', '--reset'] else: args_reset = ['--reset'] # Arrange arguments to be passed to the restarter and reset subprocess args = ' '.join(args) args_reset = ' '.join(args_reset) # Get python excutable running this script python = sys.executable # Build the command if is_bootstrap: spyder = osp.join(spyder_folder, 'bootstrap.py') else: spyderdir = osp.join(spyder_folder, 'spyder') spyder = osp.join(spyderdir, 'app', 'start.py') command = '"{0}" "{1}" {2}'.format(python, spyder, args) # Adjust the command and/or arguments to subprocess depending on the OS shell = not IS_WINDOWS # Before launching a new Spyder instance we need to make sure that the # previous one has closed. We wait for a fixed and "reasonable" amount of # time and check, otherwise an error is launched wait_time = 90 if IS_WINDOWS else 30 # Seconds for counter in range(int(wait_time / SLEEP_TIME)): if not is_pid_running(pid): break time.sleep(SLEEP_TIME) # Throttling control QApplication.processEvents() # Needed to refresh the splash else: # The old spyder instance took too long to close and restart aborts restarter.launch_error_message(error_type=CLOSE_ERROR) env = os.environ.copy() # Reset Spyder (if required) # ------------------------------------------------------------------------- if reset: restarter.set_splash_message(_('Resetting Spyder to defaults')) command_reset = '"{0}" "{1}" {2}'.format(python, spyder, args_reset) try: p = subprocess.Popen(command_reset, shell=shell, env=env) except Exception as error: restarter.launch_error_message(error_type=RESET_ERROR, error=error) else: p.communicate() pid_reset = p.pid # Before launching a new Spyder instance we need to make sure that the # reset subprocess has closed. We wait for a fixed and "reasonable" # amount of time and check, otherwise an error is launched. wait_time = 20 # Seconds for counter in range(int(wait_time / SLEEP_TIME)): if not is_pid_running(pid_reset): break time.sleep(SLEEP_TIME) # Throttling control QApplication.processEvents() # Needed to refresh the splash else: # The reset subprocess took too long and it is killed try: p.kill() except OSError as error: restarter.launch_error_message(error_type=RESET_ERROR, error=error) else: restarter.launch_error_message(error_type=RESET_ERROR) # Restart # ------------------------------------------------------------------------- restarter.set_splash_message(_('Restarting')) try: subprocess.Popen(command, shell=shell, env=env) except Exception as error: restarter.launch_error_message(error_type=RESTART_ERROR, error=error)
def make_catalog_table(self, fb, target_names, programName): #Setup local catalog. catalog = [] IDList = {} #Counter for objects with the same ID skipped = [] spatial_pixel_scale = self.get_spatial_pixel_scale(self.img_path) #Extract info from spectra files and save to catalog. for idx, fn in enumerate(fb): #For file name in file base: QApplication.processEvents() row = [] #Catch file error or load WCS: filex1d = fn if os.path.isfile(filex1d): try: headx1d = fits.open(filex1d)['extract1d'].header wcs = WCS(headx1d) w1, w2 = wcs.wcs_pix2world(0., 0., 1) w1 = w1.tolist() w2 = w2.tolist() except Exception as e: print("WCS Read Failed:", e, ":", filex1d) skipped.append(fn) continue else: continue try: head = fits.getheader(fn) except Exception as e: print("Header Read Failed:", e, ":", fn) skipped.append(fn) continue ID = target_names[idx] ID, IDList = unique_id(ID, IDList) row.append(ID) #id row.append(w1) #ra row.append(w2) #dec row.append(0.2) #slit_width for JWST MSA row.append(3.3) #slit_length for JWST MSA row.append(spatial_pixel_scale) #pix_scale (spatial_pixel_scale) row.append(head["PA_APER"]) #slit_pa row.append(self.cutout_x_size) #cutout_x_size row.append(self.cutout_y_size) #cutout_y_size catalog.append(row) #Add row to catalog if len(catalog) == 0: return None, skipped colNames = [ "id", "ra", "dec", "slit_width", "slit_length", "spatial_pixel_scale", "slit_pa", "cutout_x_size", "cutout_y_size" ] t = QTable(rows=catalog, names=colNames) t["ra"].unit = u.deg t["dec"].unit = u.deg t["slit_width"].unit = u.arcsec t["slit_length"].unit = u.arcsec t["spatial_pixel_scale"].unit = (u.arcsec / u.pix) t["slit_pa"].unit = u.deg t["cutout_x_size"].unit = u.arcsec t["cutout_y_size"].unit = u.arcsec return t, skipped
def import_data(self, filenames=None): """Import data from text file.""" title = _("Import data") if filenames is None: if self.filename is None: basedir = getcwd_or_home() else: basedir = osp.dirname(self.filename) filenames, _selfilter = getopenfilenames(self, title, basedir, iofunctions.load_filters) if not filenames: return elif is_text_string(filenames): filenames = [filenames] for filename in filenames: self.filename = to_text_string(filename) if os.name == "nt": self.filename = remove_backslashes(self.filename) ext = osp.splitext(self.filename)[1].lower() if ext not in iofunctions.load_funcs: buttons = QMessageBox.Yes | QMessageBox.Cancel answer = QMessageBox.question( self, title, _("<b>Unsupported file extension '%s'</b><br><br>" "Would you like to import it anyway " "(by selecting a known file format)?") % ext, buttons) if answer == QMessageBox.Cancel: return formats = list(iofunctions.load_extensions.keys()) item, ok = QInputDialog.getItem(self, title, _('Open file as:'), formats, 0, False) if ok: ext = iofunctions.load_extensions[to_text_string(item)] else: return load_func = iofunctions.load_funcs[ext] # 'import_wizard' (self.setup_io) if is_text_string(load_func): # Import data with import wizard error_message = None try: text, _encoding = encoding.read(self.filename) base_name = osp.basename(self.filename) editor = ImportWizard( self, text, title=base_name, varname=fix_reference_name(base_name)) if editor.exec_(): var_name, clip_data = editor.get_data() self.editor.new_value(var_name, clip_data) except Exception as error: error_message = str(error) else: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() error_message = self.shellwidget.load_data(self.filename, ext) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical( self, title, _("<b>Unable to load '%s'</b>" "<br><br>" "The error message was:<br>%s") % (self.filename, error_message)) self.refresh_table()
def start_meas(self): """Starts a new measurement.""" self.stop = False self.update_config() self.config.motor_calculus() self.config.meas_calculus() _min = getattr(self.config, 'limit_min_' + self.config.axis1) _max = getattr(self.config, 'limit_max_' + self.config.axis1) if self.config.analysis_interval > 0: if ((_min is not None and self.config.start < _min) or (_max is not None and self.config.end > _max)): _QMessageBox.warning(self, 'Warning', 'Position off the limits.', _QMessageBox.Ok) return else: if ((_max is not None and self.config.start > _max) or (_min is not None and self.config.end < _min)): _QMessageBox.warning(self, 'Warning', 'Position off the limits.', _QMessageBox.Ok) return self.mdriver.cfg_motor(1, self.config.m_ac, self.config.m_hvel) self.mdriver.cfg_motor(3, self.config.m_ac, self.config.m_hvel) self.mdriver.cfg_motor(2, self.config.m_ac, self.config.m_vvel) self.mdriver.cfg_motor(4, self.config.m_ac, self.config.m_vvel) self.mdriver.cfg_measurement_type(self.config.type) if self.config.analysis_interval > 0: self.mdriver.cfg_measurement(self.config.end + self.config.extra, self.config.m_ac, self.config.n_scans) self.mdriver.axis_move(self.config.axis1, (self.config.start - self.config.extra)) else: self.mdriver.cfg_measurement(self.config.end - self.config.extra, self.config.m_ac, self.config.n_scans) self.mdriver.axis_move(self.config.axis1, (self.config.start + self.config.extra)) _time.sleep(0.5) if self.config.axis1 == 'X': _pos = self.mdriver.in_position(1) while (_pos is 0): _pos = self.mdriver.in_position(1) else: _pos = self.mdriver.in_position(2) while (_pos is 0): _pos = self.mdriver.in_position(2) self.mdriver.cfg_trigger_signal(self.config.start, self.config.step) self.ui.gv_rawcurves.plotItem.curves.clear() self.ui.gv_rawcurves.clear() self.ui.gv_rawcurves.plotItem.setLabel('left', "Amplitude", units=self.config.meas_unit) self.ui.gv_rawcurves.plotItem.setLabel('bottom', "Position", units='mm') self.ui.gv_rawcurves.plotItem.showGrid(x=True, y=True, alpha=0.2) self.mint.config_trig_external(self.config.n_pts) self.mint.start_measurement() self.mdriver.run_motion_prog(self.config.type, self.config.axis1) self.position_timer.start(self.update_timer) # start collecting data _time0 = _time.time() _count = self.mint.get_data_count() while ((_count != self.config.n_pts - 1) and (self.stop is False)): _count = self.mint.get_data_count() if (_time.time() - _time0) > self.config.time_limit: _QMessageBox.warning( self, 'Warning', 'Timeout while ' 'waiting for integrator data.', _QMessageBox.Ok) return _QApplication.processEvents() if self.stop is False: _results = self.mint.get_data() _results = _results.strip('\n').split(',') for i in range(len(_results)): try: if self.config.meas_unit == 'V.s': _results[i] = float(_results[i].strip(' WB')) else: _results[i] = float(_results[i].strip(' V')) except Exception: _traceback.print_exc(file=_sys.stdout) if 'NAN' in _results[i]: _QMessageBox.warning( self, 'Warning', 'Integrator tension over-range.\n' 'Please configure a lower gain.', _QMessageBox.Ok) return self.meas.raw_data = _np.array(_results, dtype=_np.float64) try: _tmp = self.meas.raw_data.reshape( self.config.n_scans, self.config.n_pts - 1).transpose() except Exception: _traceback.print_exc(file=_sys.stdout) return px = _np.linspace(self.config.start, self.config.end, self.config.n_pts) px = px[1:] self.ui.gv_rawcurves.plotItem.plot(px, self.meas.raw_data, pen=(0, 0, 0), width=3, symbol=None) px = px * 0.001 data = self.meas.raw_data / (self.config.step * 0.001) print(self.meas.raw_data) print(stats.linregress(px, data))
def setStatus(self, message): self.status.setText(message) QApplication.processEvents()
def start_one_measurement(self, silent=False): if not self.move_to_initial_position(): return False if self.global_config.measure_position_1: if not silent: msg = _QCoreApplication.translate( '', 'Place the magnet in Position 1.') title = _QCoreApplication.translate('', 'Information') reply = _QMessageBox.information( self, title, msg, _QMessageBox.Ok, _QMessageBox.Cancel) if reply == _QMessageBox.Cancel: self.stop_measurement(silent=True) return False if not self.move_half_turn(): return False _QApplication.processEvents() gain = self.global_config.gain_position_1 if not self.measure_position(gain=gain): self.ui.pbt_start_measurement.setEnabled(True) return False self.integrated_voltage_position_1 = _np.array( self.integrated_voltage) if self.stop: return False if not self.move_to_initial_position(): return False if self.global_config.measure_position_2: if not silent: msg = _QCoreApplication.translate( '', 'Place the magnet in Position 2.') title = _QCoreApplication.translate('', 'Information') reply = _QMessageBox.information( self, title, msg, _QMessageBox.Ok, _QMessageBox.Cancel) if reply == _QMessageBox.Cancel: self.stop_measurement(silent=True) return False if not self.move_half_turn(): return False _QApplication.processEvents() gain = self.global_config.gain_position_2 if not self.measure_position(gain=gain): self.ui.pbt_start_measurement.setEnabled(True) return False self.integrated_voltage_position_2 = _np.array( self.integrated_voltage) if self.stop: return False gc = self.global_config self.measurement_data.block_name = gc.block_name self.measurement_data.block_temperature = gc.block_temperature self.measurement_data.advanced_options_id = self.advanced_options.idn self.measurement_data.configuration_id = gc.idn self.measurement_data.comments = gc.comments m, mstd = self.measurement_data.set_magnetization_components( self.integrated_voltage_position_1, self.integrated_voltage_position_2, self.offset_position_1, self.offset_position_2, self.advanced_options.coil_radius*1e-3, self.advanced_options.coil_distance_center*1e-3, self.advanced_options.coil_turns, self.block_volume*1e-9) _QApplication.processEvents() std_tol = _utils.STD_TOLERANCE if any([v > std_tol for v in mstd]): self.measurement_error_count += 1 msg = _QCoreApplication.translate( '', "Standard deviation outside tolerance. Repeat measurement?") title = _QCoreApplication.translate('', 'Warning') reply = _QMessageBox.question( self, title, msg, _QMessageBox.No, _QMessageBox.Yes) if reply == _QMessageBox.Yes: if self.measurement_error_count < 3: self.integrated_voltage_position_1 = [] self.integrated_voltage_position_2 = [] return self.start_one_measurement() else: self.measurement_error_count = 0 return False if not self.save_measurement_data(): return False self.update_magnetization_values(m, mstd) self.mx_list.append(m[0]) self.my_list.append(m[1]) self.mz_list.append(m[2]) self.plot_integrated_voltage() _QApplication.processEvents() if not self.move_to_initial_position(): return False if self.stop: return False self.measurement_error_count = 0 return True
def import_data(self, filenames=None): """Import data from text file""" title = _("Import data") if filenames is None: if self.filename is None: basedir = getcwd() else: basedir = osp.dirname(self.filename) filenames, _selfilter = getopenfilenames(self, title, basedir, iofunctions.load_filters) if not filenames: return elif is_text_string(filenames): filenames = [filenames] for filename in filenames: self.filename = to_text_string(filename) ext = osp.splitext(self.filename)[1].lower() if ext not in iofunctions.load_funcs: buttons = QMessageBox.Yes | QMessageBox.Cancel answer = QMessageBox.question( self, title, _("<b>Unsupported file extension '%s'</b><br><br>" "Would you like to import it anyway " "(by selecting a known file format)?") % ext, buttons) if answer == QMessageBox.Cancel: return formats = list(iofunctions.load_extensions.keys()) item, ok = QInputDialog.getItem(self, title, _('Open file as:'), formats, 0, False) if ok: ext = iofunctions.load_extensions[to_text_string(item)] else: return load_func = iofunctions.load_funcs[ext] # 'import_wizard' (self.setup_io) if is_text_string(load_func): # Import data with import wizard error_message = None try: text, _encoding = encoding.read(self.filename) if self.is_internal_shell: self.editor.import_from_string(text) else: base_name = osp.basename(self.filename) editor = ImportWizard( self, text, title=base_name, varname=fix_reference_name(base_name)) if editor.exec_(): var_name, clip_data = editor.get_data() monitor_set_global(self._get_sock(), var_name, clip_data) except Exception as error: error_message = str(error) else: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() if self.is_internal_shell: namespace, error_message = load_func(self.filename) interpreter = self.shellwidget.interpreter for key in list(namespace.keys()): new_key = fix_reference_name( key, blacklist=list(interpreter.namespace.keys())) if new_key != key: namespace[new_key] = namespace.pop(key) if error_message is None: interpreter.namespace.update(namespace) else: error_message = monitor_load_globals( self._get_sock(), self.filename, ext) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical( self, title, _("<b>Unable to load '%s'</b>" "<br><br>Error message:<br>%s") % (self.filename, error_message)) self.refresh_table()
def read_temperature(self): try: if not _multimeter.connected: msg = _QCoreApplication.translate( '', 'Multimeter not connected.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical(self, title, msg, _QMessageBox.Ok) return False msg = _QCoreApplication.translate( '', 'Place temperature sensor on the magnet.') title = _QCoreApplication.translate('', 'Information') reply = _QMessageBox.information( self, title, msg, _QMessageBox.Ok, _QMessageBox.Cancel) if reply == _QMessageBox.Cancel: return False _multimeter.config_resistance_4w(wait=0.5) nr_readings = self.advanced_options.temperature_nr_readings freq = self.advanced_options.temperature_reading_frequency msg = _QCoreApplication.translate( '', 'Measuring temperature...') prg_dialog = _QProgressDialog( msg, _QCoreApplication.translate('', 'Stop'), 0, nr_readings) prg_dialog.setWindowTitle(_QCoreApplication.translate( '', 'Information')) prg_dialog.autoClose() prg_dialog.show() temperature_list = [] for i in range(nr_readings): reading = _multimeter.read() temperature = _multimeter.pt100_resistance_to_temperature( reading) temperature_list.append(temperature) for j in range(10): _time.sleep(1/freq/10) _QApplication.processEvents() if prg_dialog.wasCanceled(): break prg_dialog.setValue(i+1) if len(temperature_list) == 0: temperature_avg = 0 else: temperature_avg = _np.mean(temperature_list) if prg_dialog.wasCanceled(): return False self.ui.sbd_block_temperature.setValue(temperature_avg) self.config.block_temperature = temperature_avg if len(temperature_list) != 0: diff = _np.max(temperature_list) - _np.min(temperature_list) if diff > _utils.TEMPERATURE_DIFF_TOLERANCE: msg = _QCoreApplication.translate( '', 'Temperature diference outside tolerance.') title = _QCoreApplication.translate('', 'Warning') _QMessageBox.warning(self, title, msg, _QMessageBox.Ok) return True except Exception: msg = _QCoreApplication.translate( '', 'Failed to read temperature.') title = _QCoreApplication.translate('', 'Failure') _QMessageBox.critical(self, title, msg, _QMessageBox.Ok) _traceback.print_exc(file=_sys.stdout) return False
def report_progress_percentage(self, percentage): QApplication.processEvents() self.progressBar.setValue(percentage)
def _set_value(self, value): self.pbar.setValue(value) QApplication.processEvents()
## NUEVAS LINEAS # Crea y muestra el splash screen path = Path('imgs', 'splash_screen_kali.png') splash_pix = QPixmap(str(path)) splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint) splash.setEnabled(False) splash.show() # Esto es un simple contador/temporizador para mostrar en la pantalla el splash screen. # En el futuro haremos que esto sea más útil for i in range(0, 5): msg = ('<h1><font color="white">' f'Listo en {5-i}s' '</font></h1>') splash.showMessage(msg, int(Qt.AlignBottom) | int(Qt.AlignCenter), Qt.black) time.sleep(1) app.processEvents() w = MiVentana() splash.finish(w) sys.exit(app.exec_()) ''' En esta parte ya hacemos uso de algunas de las nuevas cosas que hemos importado: - path: simplemente guarda la ruta a la imagen que vamos a usar de fondo. Esto no es código relacionado con Qt en sí. - splash_pix: es una instancia de QPixmap. Nos guarda la imagen en una forma que entiende Qt. - splash es la instancia de QSplashScreen. Recibe la imagen en la forma en que la entiende Qt, splash_pix, y, además, le pasamos una marca o flag, Qt.WindowStaysOnTopHint, que le indica que debe permanecer delante del resto de ventanas en el escritorio. - splash.setEnabled(False): nos permite decirle al programa que no esté activo a eventos que le podamos pasar, como un click, ya que podemos tener algún efecto indeseado.
def _set_description(self, desc): self.description_label.setText(desc) QApplication.processEvents()
def show_list(self, completion_list, position): if position is None: # Somehow the position was not saved. # Hope that the current position is still valid self.position = self.textedit.textCursor().position() elif self.textedit.textCursor().position() < position: # hide the text as we moved away from the position return else: self.position = position # Completions are handled differently for the Internal # console. if not isinstance(completion_list[0], dict): self.is_internal_console = True self.completion_list = completion_list self.clear() icons_map = {CompletionItemKind.PROPERTY: 'attribute', CompletionItemKind.VARIABLE: 'attribute', CompletionItemKind.METHOD: 'method', CompletionItemKind.FUNCTION: 'function', CompletionItemKind.CLASS: 'class', CompletionItemKind.MODULE: 'module', CompletionItemKind.CONSTRUCTOR: 'method', CompletionItemKind.REFERENCE: 'attribute'} for completion in completion_list: if not self.is_internal_console: icon = icons_map.get(completion['kind'], 'no_match') self.addItem( QListWidgetItem(ima.icon(icon), completion['insertText'])) else: # This is used by the Internal console. self.addItem(QListWidgetItem(completion[0])) self.setCurrentRow(0) QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.show() self.setFocus() self.raise_() # Retrieving current screen height desktop = QApplication.desktop() srect = desktop.availableGeometry(desktop.screenNumber(self)) screen_right = srect.right() screen_bottom = srect.bottom() point = self.textedit.cursorRect().bottomRight() point = self.textedit.calculate_real_position(point) point = self.textedit.mapToGlobal(point) # Computing completion widget and its parent right positions comp_right = point.x() + self.width() ancestor = self.parent() if ancestor is None: anc_right = screen_right else: anc_right = min([ancestor.x() + ancestor.width(), screen_right]) # Moving completion widget to the left # if there is not enough space to the right if comp_right > anc_right: point.setX(point.x() - self.width()) # Computing completion widget and its parent bottom positions comp_bottom = point.y() + self.height() ancestor = self.parent() if ancestor is None: anc_bottom = screen_bottom else: anc_bottom = min([ancestor.y() + ancestor.height(), screen_bottom]) # Moving completion widget above if there is not enough space below x_position = point.x() if comp_bottom > anc_bottom: point = self.textedit.cursorRect().topRight() point = self.textedit.mapToGlobal(point) point.setX(x_position) point.setY(point.y() - self.height()) if ancestor is not None: # Useful only if we set parent to 'ancestor' in __init__ point = ancestor.mapFromGlobal(point) self.move(point) if not self.is_internal_console: tooltip_point = QPoint(point) tooltip_point.setX(point.x() + self.width()) tooltip_point.setY(point.y() - (3 * self.height()) // 4) for completion in completion_list: completion['point'] = tooltip_point if to_text_string(to_text_string( self.textedit.get_current_word(completion=True))): # When initialized, if completion text is not empty, we need # to update the displayed list: self.update_current() # signal used for testing self.sig_show_completions.emit(completion_list)
def run_opensbml(self, filenames=None, goto=None, word='', editorwindow=None, processevents=True): """Prompt the user to load a SBML file, translate to antimony, and display in a new window""" editorwindow = None #Used in editor.load processevents = True #Used in editor.load editor = self.main.editor basedir = getcwd() if CONF.get('workingdir', 'editor/open/browse_scriptdir'): c_fname = editor.get_current_filename() if c_fname is not None and c_fname != editor.TEMPFILE_PATH: basedir = os.path.dirname(c_fname) editor.redirect_stdio.emit(False) parent_widget = editor.get_current_editorstack() selectedfilter = '' filters = 'SBML files (*.sbml *.xml);;All files (*.*)' filenames, _selfilter = getopenfilenames(parent_widget, _("Open SBML file"), basedir, filters, selectedfilter=selectedfilter) editor.redirect_stdio.emit(True) if filenames: filenames = [os.path.normpath(fname) for fname in filenames] if CONF.get('workingdir', 'editor/open/auto_set_to_basedir'): directory = os.path.dirname(filenames[0]) editor.emit(Signal("open_dir(QString)"), directory) else: #The file dialog box was closed without selecting a file. return focus_widget = QApplication.focusWidget() if editor.dockwidget and not editor.ismaximized and\ (not editor.dockwidget.isAncestorOf(focus_widget)\ and not isinstance(focus_widget, CodeEditor)): editor.dockwidget.setVisible(True) editor.dockwidget.setFocus() editor.dockwidget.raise_() def _convert(fname): fname = os.path.abspath(encoding.to_unicode_from_fs(fname)) if os.name == 'nt' and len(fname) >= 2 and fname[1] == ':': fname = fname[0].upper() + fname[1:] return fname if hasattr(filenames, 'replaceInStrings'): # This is a QStringList instance (PyQt API #1), converting to list: filenames = list(filenames) if not isinstance(filenames, list): filenames = [_convert(filenames)] else: filenames = [_convert(fname) for fname in list(filenames)] for index, filename in enumerate(filenames): p = re.compile('(.xml$|.sbml$)') pythonfile = p.sub('_antimony.py', filename) if (pythonfile == filename): pythonfile = filename + "_antimony.py" current_editor = editor.set_current_filename( pythonfile, editorwindow) if current_editor is not None: # -- TODO: Do not open an already opened file pass else: # -- Not an existing opened file: if not os.path.isfile(filename): continue # -- current_es = editor.get_current_editorstack(editorwindow) # Creating the editor widget in the first editorstack (the one # that can't be destroyed), then cloning this editor widget in # all other editorstacks: finfo, newname = self.load_and_translate( filename, pythonfile, editor) finfo.path = editor.main.get_spyder_pythonpath() editor._clone_file_everywhere(finfo) current_editor = current_es.set_current_filename(newname) #if (current_editor is not None): # editor.register_widget_shortcuts("Editor", current_editor) current_es.analyze_script() if (current_editor is not None): current_editor.clearFocus() current_editor.setFocus() current_editor.window().raise_() if processevents: QApplication.processEvents()
def make_napari_viewer( qtbot, request: 'FixtureRequest', napari_plugin_manager ): """A fixture function that creates a napari viewer for use in testing. Use this fixture as a function in your tests: viewer = make_napari_viewer() It accepts all the same arguments as napari.Viewer, plus the following test-related paramaters: ViewerClass : Type[napari.Viewer], optional Override the viewer class being used. By default, will use napari.viewer.Viewer strict_qt : bool or str, optional If True, a check will be performed after test cleanup to make sure that no top level widgets were created and *not* cleaned up during the test. If the string "raise" is provided, an AssertionError will be raised. Otherwise a warning is emitted. By default, this is False unless the test is being performed within the napari package. This can be made globally true by setting the 'NAPARI_STRICT_QT' environment variable. block_plugin_discovery : bool, optional Block discovery of non-builtin plugins. Note: plugins can still be manually registered by using the 'napari_plugin_manager' fixture and the `napari_plugin_manager.register()` method. By default, True. Examples -------- >>> def test_adding_shapes(make_napari_viewer): ... viewer = make_napari_viewer() ... viewer.add_shapes() ... assert len(viewer.layers) == 1 >>> def test_something_with_plugins(make_napari_viewer): ... viewer = make_napari_viewer(block_plugin_discovery=False) >>> def test_something_with_strict_qt_tests(make_napari_viewer): ... viewer = make_napari_viewer(strict_qt=True) """ from qtpy.QtWidgets import QApplication from napari import Viewer from napari.utils.settings import SETTINGS SETTINGS.reset() viewers: List[Viewer] = [] # may be overridden by using `make_napari_viewer(strict=True)` _strict = False initial = QApplication.topLevelWidgets() prior_exception = getattr(sys, 'last_value', None) is_internal_test = request.module.__name__.startswith("napari.") def actual_factory( *model_args, ViewerClass=Viewer, strict_qt=is_internal_test or os.getenv("NAPARI_STRICT_QT"), block_plugin_discovery=True, **model_kwargs, ): nonlocal _strict _strict = strict_qt if not block_plugin_discovery: napari_plugin_manager.discovery_blocker.stop() should_show = request.config.getoption("--show-napari-viewer") model_kwargs['show'] = model_kwargs.pop('show', should_show) viewer = ViewerClass(*model_args, **model_kwargs) viewers.append(viewer) return viewer yield actual_factory # Some tests might have the viewer closed, so this call will not be able # to access the window. with suppress(AttributeError): SETTINGS.reset() # close viewers, but don't saving window settings while closing for viewer in viewers: if hasattr(viewer.window, '_qt_window'): with patch.object( viewer.window._qt_window, '_save_current_window_settings' ): viewer.close() else: viewer.close() # only check for leaked widgets if an exception was raised during the test, # or "strict" mode was used. if _strict and getattr(sys, 'last_value', None) is prior_exception: QApplication.processEvents() leak = set(QApplication.topLevelWidgets()).difference(initial) # still not sure how to clean up some of the remaining vispy # vispy.app.backends._qt.CanvasBackendDesktop widgets... if any([n.__class__.__name__ != 'CanvasBackendDesktop' for n in leak]): # just a warning... but this can be converted to test errors # in pytest with `-W error` if _strict == 'raise': raise AssertionError(f'Widgets leaked!: {leak}') else: warnings.warn(f'Widgets leaked!: {leak}')