def beam_cal_pos_data_changed(self, who_changed, new_data_dict): """ Change data in table. Set background color to highlight changes if who_changed == 1 : changes from calibration if who_changed == 0 : changes from beam position """ if who_changed == 0: return self.update_gui() if new_data_dict: pos_name = new_data_dict["zoom_tag"] else: pos_name = self.multipos_hwobj.get_value() table = self.ui_widgets_manager.calibration_table for index_row in range(table.rowCount()): if table.item(index_row, 0).text() == pos_name: table.item(index_row, 1).setBackground( qt_import.QColor(qt_import.Qt.yellow)) table.item(index_row, 2).setBackground( qt_import.QColor(qt_import.Qt.yellow))
def set_color(self, color): if not color: self.qtcolor = None self.color = None colors.set_widget_color( self.change_color_button, colors.BUTTON_ORIGINAL, qt_import.QPalette.Button, ) else: try: rgb = color.rgb() except BaseException: try: self.qtcolor = qt_import.QColor(color) except BaseException: self.qtcolor = qt_import.QColor(qt_import.Qt.green) self.color = self.qtcolor.rgb() else: self.color = self.qtcolor.rgb() else: self.qtcolor = color self.color = rgb colors.set_widget_color( self.change_color_button, self.qtcolor, qt_import.QPalette.Button ) self.parent.cellChanged.emit(self.row, self.col)
def beam_pos_cal_data_changed(self, who_changed, new_data_dict): self.fill_config_table() if new_data_dict: current_pos_name = new_data_dict["zoom_tag"] else: current_pos_name = self.multipos_hwobj.get_value() table = self.ui_widgets_manager.configuration_table self.ui_widgets_manager.configuration_table.itemChanged.disconnect( self.configuration_table_item_changed) for row_index in range(table.rowCount()): if table.item(row_index, 0).text() == current_pos_name: if who_changed == 0: table.item(row_index, 1).setBackground( qt_import.QColor(qt_import.Qt.yellow)) table.item(row_index, 2).setBackground( qt_import.QColor(qt_import.Qt.yellow)) elif who_changed == 1: table.item(row_index, 3).setBackground( qt_import.QColor(qt_import.Qt.yellow)) table.item(row_index, 4).setBackground( qt_import.QColor(qt_import.Qt.yellow)) self.ui_widgets_manager.configuration_table.itemChanged.connect( self.configuration_table_item_changed)
def paint(self, painter, option, widget): pen = qt_import.QPen(qt_import.Qt.SolidLine) pen.setWidth(1) pen.setColor(qt_import.Qt.black) painter.setPen(pen) if self.isSelected(): brush_color = qt_import.QColor(204, 255, 204) else: brush_color = qt_import.QColor(203, 212, 246) self.custom_brush.setColor(brush_color) painter.setBrush(self.custom_brush) painter.drawEllipse(-20, -20, 40, 40) paint_rect = qt_import.QRect(-20, -20, 40, 40) painter.drawText(paint_rect, qt_import.Qt.AlignCenter, str(self.index + 1))
class IntSpinBox(qt_import.QSpinBox): """Standard integer (spinbox) widget""" CHANGED_COLOR = qt_import.QColor(255, 165, 0) def __init__(self, parent, options): qt_import.QSpinBox.__init__(self, parent) self.lineEdit().setAlignment(qt_import.Qt.AlignLeft) self.__name = options["variableName"] if "unit" in options: self.setSuffix(" " + options["unit"]) if "defaultValue" in options: val = int(options["defaultValue"]) self.setValue(val) if "upperBound" in options: self.setMaximum(int(options["upperBound"])) else: self.setMaximum(sys.maxsize) if "lowerBound" in options: self.setMinimum(int(options["lowerBound"])) if "tooltip" in options: self.setToolTip(options["tooltip"]) def set_value(self, value): self.setValue(int(value)) def get_value(self): val = int(self.value()) return ConvertUtils.text_type(val) def get_name(self): return self.__name
def populate_widget(self, item): dcg_queue_item = item.get_queue_entry() dcg_child_list = [] sw_list = [] if dcg_queue_item.interleave_sw_list: sw_list = dcg_queue_item.interleave_sw_list for child in dcg_queue_item.interleave_items: dcg_child_list.append(child["data_model"]) else: for children in dcg_queue_item.get_queue_entry_list(): if isinstance(children.get_view(), queue_item.DataCollectionQueueItem): dcg_child_list.append(children.get_data_model()) acq_par = ( children.get_data_model().acquisitions[0].acquisition_parameters ) sw_list.append( [ len(sw_list), 0, acq_par.first_image, acq_par.num_images, acq_par.osc_start, acq_par.osc_range * acq_par.num_images, ] ) for sw in sw_list: color = colors.get_random_numpy_color() sw.append(color) self.subwedge_table.setRowCount(0) for sw in sw_list: acq_par = dcg_child_list[sw[0]].acquisitions[0].acquisition_parameters row = self.subwedge_table.rowCount() self.subwedge_table.setRowCount(row + 1) param_list = ( str(acq_par.osc_start), str(acq_par.osc_range), str(acq_par.num_images), str(acq_par.exp_time), str(acq_par.energy), str(acq_par.transmission), str(acq_par.resolution), ) # color = colors.get_random_color() # sw.append(color) for col in range(7): self.subwedge_table.setItem( row, col, qt_import.QTableWidgetItem(param_list[col]) ) color = qt_import.QColor( int(sw[-1][0] * 255), int(sw[-1][0] * 255), int(sw[-1][0] * 255) ) color.setAlpha(100) self.subwedge_table.item(row, col).setBackground(color) # QtGui.QColor(colors.TASK_GROUP[sw[0]])) self.polar_scater_widget.draw_multiwedge_scater(sw_list)
def __init__(self, *args): QPeriodicTable.QPeriodicTable.__init__(self, *args) self.elements_dict = {} if PYMCA_IMPORTED == 5: self.sigElementClicked.connect(self.table_element_clicked) else: qt_import.QObject.connect( self, qt_import.SIGNAL("elementClicked"), self.table_element_clicked ) for b in self.eltButton: self.eltButton[b].colors[0] = qt_import.QColor(qt_import.Qt.green) self.eltButton[b].colors[1] = qt_import.QColor(qt_import.Qt.darkGreen) self.eltButton[b].setEnabled(False) for el in QPeriodicTable.Elements: symbol = el[0] self.elements_dict[symbol] = el
def change_color_clicked(self): """Opens color dialog to choose color""" new_color = qt_import.QColorDialog.getColor( self.qtcolor or qt_import.QColor("white"), None, "Select a color" ) if new_color.isValid(): self.set_color(new_color)
def centring_successful(self): """ Used to give feedback to user: table cells' background to green """ table = self.ui_widgets_manager.aligment_table table.setRowCount(self.points_for_aligment) for row in range(table.rowCount()): for column in range(table.columnCount()): table.item(row, column).setBackground(qt_import.QColor(qt_import.Qt.green)) self.ui_widgets_manager.number_points_spinbox.setEnabled(True)
def set_editing(self, editing): self.editing = editing if self.editing: colors.set_widget_color( self.position_spinbox.lineEdit(), qt_import.QColor(255, 165, 0), qt_import.QPalette.Base, ) else: # restore last position from motor self.position_changed(self.motor_hwobj.get_value())
def configuration_table_item_changed(self, item): validated_value = self.validate_cell_value(item.text()) item.setText(str(validated_value)) item.setBackground(qt_import.QColor(qt_import.Qt.yellow)) # create new dict from new data table = self.ui_widgets_manager.configuration_table item_row = item.row() item_col = item.column() if item_col in (1, 2): who_changed = 0 elif item_col in (3, 4): who_changed = 1 else: who_changed = 2 edited_key = table.item(item_row, 0).text() dict_elem = {} dict_elem["zoom_tag"] = edited_key dict_elem["beam_pos_x"] = int( self.validate_cell_value(table.item(item_row, 1).text())) dict_elem["beam_pos_y"] = int( self.validate_cell_value(table.item(item_row, 2).text())) resox = self.validate_cell_value(table.item(item_row, 3).text()) dict_elem["cal_x"] = float(resox) resoy = self.validate_cell_value(table.item(item_row, 4).text()) dict_elem["cal_y"] = float(resoy) dict_elem["light"] = int( self.validate_cell_value(table.item(item_row, 5).text())) dict_elem["zoom"] = int( self.validate_cell_value(table.item(item_row, 6).text())) self.multipos_hwobj.edit_data(dict_elem, edited_key, who_changed)
def __init__(self, steps, *args, **kwargs): super(_Bar, self).__init__(*args, **kwargs) self.setSizePolicy(qt_import.QSizePolicy.MinimumExpanding, qt_import.QSizePolicy.MinimumExpanding) if isinstance(steps, list): # list of colours. self.n_steps = len(steps) self.steps = steps elif isinstance(steps, int): # int number of bars, defaults to red. self.n_steps = steps self.steps = ['red'] * steps else: raise TypeError('steps must be a list or int') self._bar_solid_percent = 0.8 self._background_color = qt_import.QColor('black') self._padding = 4.0 # n-pixel gap around edge.
def paintEvent(self, e): painter = qt_import.QPainter(self) brush = qt_import.QBrush() brush.setColor(self._background_color) brush.setStyle(qt_import.Qt.SolidPattern) rect = qt_import.QRect(0, 0, painter.device().width(), painter.device().height()) painter.fillRect(rect, brush) # Get current state. parent = self.parent() vmin, vmax = parent.minimum(), parent.maximum() value = parent.value() # Define our canvas. d_height = painter.device().height() - (self._padding * 2) d_width = painter.device().width() - (self._padding * 2) # Draw the bars. step_size = d_height / self.n_steps bar_height = step_size * self._bar_solid_percent bar_spacer = step_size * (1 - self._bar_solid_percent) / 2 # Calculate the y-stop position, from the value in range. pc = (value - vmin) / (vmax - vmin) n_steps_to_draw = int(pc * self.n_steps) for n in range(n_steps_to_draw): brush.setColor(qt_import.QColor(self.steps[n])) rect = qt_import.QRect( self._padding, self._padding + d_height - ((1 + n) * step_size) + bar_spacer, d_width, bar_height) painter.fillRect(rect, brush) painter.end()
class LogBarBrick(BaseWidget): COLORS = { logging.NOTSET: qt_import.Qt.lightGray, logging.DEBUG: qt_import.Qt.darkGreen, logging.INFO: qt_import.Qt.darkBlue, logging.WARNING: qt_import.QColor(255, 185, 56), logging.ERROR: qt_import.Qt.red, logging.CRITICAL: qt_import.Qt.red, } def __init__(self, *args): BaseWidget.__init__(self, *args) # Hardware objects ---------------------------------------------------- # Internal values ----------------------------------------------------- self.max_log_lines = -1 self.test_mode = False # Properties ---------------------------------------------------------- self.add_property("maxLogLines", "integer", -1) # Signals ------------------------------------------------------------- # Slots --------------------------------------------------------------- # Graphic elements ---------------------------------------------------- self._status_bar_widget = LogBarWidget(self) # Layout -------------------------------------------------------------- _main_hlayout = qt_import.QHBoxLayout(self) _main_hlayout.addWidget(self._status_bar_widget) _main_hlayout.setSpacing(0) _main_hlayout.setContentsMargins(2, 2, 2, 2) # SizePolicies -------------------------------------------------------- # Qt signal/slot connections ------------------------------------------ # Other --------------------------------------------------------------- gui_log_handler.GUILogHandler().register(self) def property_changed(self, property_name, old_value, new_value): if property_name == "maxLogLines": self.max_log_lines = new_value else: BaseWidget.property_changed(self, property_name, old_value, new_value) def test(self): self.test_mode = True def customEvent(self, event): """Event to add a new log record""" self.append_log_record(event.record) def append_log_record(self, record): """Appends a new log line to the text edit """ if self.is_running() and record.name in ("user_level_log", "GUI"): msg = record.getMessage() level = record.getLevel() self._status_bar_widget.text_edit.setTextColor(LogBarBrick.COLORS[level]) self._status_bar_widget.text_edit.append( "[%s %s] %s" % (record.getDate(), record.getTime(), msg) ) # if level == logging.WARNING or level == logging.ERROR: # self._status_bar_widget.toggle_background_color() text_document = self._status_bar_widget.text_edit.document() if ( self.max_log_lines > -1 and text_document.blockCount() > self.max_log_lines ): cursor = qt_import.QTextCursor(text_document.firstBlock()) cursor.select(qt_import.QTextCursor.BlockUnderCursor) cursor.removeSelectedText() cursor.deleteChar() if level == logging.ERROR: self._status_bar_widget.toggle_background_color() if self.test_mode: assert False, msg
def create_app(gui_config_path=None, core_config_path=None): """Main run method""" parser = OptionParser( usage= "usage: %prog <gui definition file> <core configuration paths> [options]" ) parser.add_option( "", "--logFile", action="store", type="string", help="Log file", dest="logFile", metavar="FILE", default="", ) parser.add_option( "", "--logLevel", action="store", type="string", help="Log level", dest="logLevel", default="INFO", ) parser.add_option( "", "--logTemplate", action="store", type="string", help="Log template", dest="logTemplate", default="", ) parser.add_option( "", "--bricksDirs", action="store", type="string", help="Additional directories for bricks search " + "path (you can also use the CUSTOM_BRICKS_PATH " + "environment variable)", dest="bricksDirs", metavar="dir1" + os.path.pathsep + "dir2...dirN", default="", ) parser.add_option( "", "--guiConfigPath", action="store", type="string", help="Path to the mxcube gui configuration file " + "Alternatively MXCUBE_GUI_CONFIG_PATH env variable" + "can be used", metavar="directory", dest="coreConfigPath", default="", ) parser.add_option( "", "--coreConfigPath", action="store", type="string", help="Path to the directory containing mxcubecore " + "configuration files. " + "Alternatively MXCUBE_CORE_CONFIG_PATH env variable" + "can be used", dest="guiConfigPath", default="", ) parser.add_option( "", "--hardwareObjectsDirs", action="store", type="string", help="Additional directories for " + "Hardware Objects search path (you can also use " + "the CUSTOM_HARDWARE_OBJECTS_PATH environment " + "variable)", dest="hardwareObjectsDirs", metavar="dir1" + os.path.pathsep + "dir2...dirN", default="", ) parser.add_option( "-d", "", action="store_true", dest="designMode", default=False, help="Start mxcube in design mode", ) parser.add_option( "-m", "", action="store_true", dest="showMaximized", default=False, help="Maximize main window", ) parser.add_option( "", "--no-border", action="store_true", dest="noBorder", default=False, help="Does not show borders on main window", ) parser.add_option( "", "--style", action="store", type="string", help="Visual style of the application (windows, motif," + "cde, plastique, windowsxp, or macintosh)", dest="appStyle", default=None, ) parser.add_option( "", "--userFileDir", action="store", type="string", help="User settings file stores application related settings " + "(window size and position). If not defined then user home " + "directory is used", dest="userFileDir", default=None, ) parser.add_option( "-v", "--version", action="store_true", default=False, dest="version", help="Shows version", ) parser.add_option( "", "--mockupMode", action="store_true", default=False, dest="mockupMode", help="Runs MXCuBE with mockup configuration", ) parser.add_option("", "--pyqt4", action="store_true", default=None, help="Force to use PyQt4") parser.add_option("", "--pyqt5", action="store_true", default=None, help="Force to use PyQt5") parser.add_option("", "--pyside", action="store_true", default=None, help="Force to use PySide") (opts, args) = parser.parse_args() if opts.version: from mxcubeqt import __version__ print(__version__) exit(0) log_file = start_log(opts.logFile, opts.logLevel) log_template = opts.logTemplate hwobj_directories = opts.hardwareObjectsDirs.split(os.path.pathsep) custom_bricks_directories = opts.bricksDirs.split(os.path.pathsep) user_file_dir = opts.userFileDir or os.path.join(os.environ["HOME"], ".mxcube") app_style = opts.appStyle if not gui_config_path: if opts.guiConfigPath: gui_config_path = opts.guiConfigPath elif opts.mockupMode: gui_config_path = MOCKUP_CONFIG_PATH else: gui_config_path = os.environ.get("MXCUBE_GUI_CONFIG_PATH") if not core_config_path: if opts.coreConfigPath: core_config_path = opts.coreConfigPath elif opts.mockupMode: core_config_path = MOCKUP_CORE_CONFIG_PATH else: # try to set Hardware Repository server from environment core_config_path = os.environ.get("MXCUBE_CORE_CONFIG_PATH") # add bricks directories and hardware objects directories from environment try: custom_bricks_directories += os.environ.get("CUSTOM_BRICKS_PATH", "").split(os.path.pathsep) except KeyError: pass try: hwobj_directories += os.environ.get("CUSTOM_HARDWARE_OBJECTS_PATH", "").split(os.path.pathsep) except KeyError: pass try: if not os.path.exists(user_file_dir): os.makedirs(user_file_dir) except BaseException: HWR_LOGGER.exception("Unable to create user files directory: %s" % user_file_dir) custom_bricks_directories = [ _directory for _directory in custom_bricks_directories if _directory ] hwobj_directories = [ _directory for _directory in hwobj_directories if _directory ] main_application = qt_import.QApplication([]) if app_style: main_application.setStyle(app_style) if len(args) >= 1: if len(args) == 1: gui_config_file = os.path.abspath(args[0]) else: parser.error("Too many arguments.") sys.exit(1) if (len( os.popen("ps -aef | grep 'python' -i | grep 'mxcubecore'" + " | grep -v 'grep' | awk '{ print $3 }'").read().strip(). split("\n")) > 1): qt_import.QMessageBox.warning( None, "Warning", "Another instance of MXCuBE is running.\n", qt_import.QMessageBox.Ok, ) # sys.exit(1) # configure modules if hwobj_directories: # Must be done before init_hardware_repository HWR.add_hardware_objects_dirs(hwobj_directories) HWR.init_hardware_repository(core_config_path) HWR.set_user_file_directory(user_file_dir) if custom_bricks_directories: add_custom_bricks_dirs(custom_bricks_directories) log_lockfile = None if len(log_file) > 0: if gui_config_file: set_logging_name(os.path.basename(gui_config_file), log_template) log_lock_filename = os.path.join( tempfile.gettempdir(), ".%s.lock" % os.path.basename(log_file)) log_ok = True try: log_lockfile = open(log_lock_filename, "w") except BaseException: log_ok = False else: try: os.chmod(log_lock_filename, 0o666) except BaseException: pass try: fcntl.lockf(log_lockfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) except BaseException: log_ok = False try: log_lockfile.close() except BaseException: pass if not log_ok: index = 1 logfile_details = os.path.splitext(log_file) log_file = "" while index < 10: log_file2 = "%s.%d%s" % (logfile_details[0], index, logfile_details[1]) log_lock_filename2 = os.path.join( tempfile.gettempdir(), ".%s.lock" % os.path.basename(log_file2)) try: log_lockfile = open(log_lock_filename2, "w") except BaseException: pass else: try: os.chmod(log_lock_filename2, 0o666) except BaseException: pass try: fcntl.lockf(log_lockfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) except BaseException: pass else: log_ok = True if log_ok: log_file = log_file2 break index += 1 set_log_file(log_file) HWR_LOGGER.info( "==============================================================================" ) if opts.designMode: HWR_LOGGER.info("Starting MXCuBE Qt in designer mode...") else: HWR_LOGGER.info("Starting MXCuBE Qt...") HWR_LOGGER.info("GUI file: %s" % (gui_config_path or "unnamed")) if len(log_file) > 0: HWR_LOGGER.info("Log file: %s" % log_file) HWR_LOGGER.info("User file directory: %s" % user_file_dir) HWR_LOGGER.info("System info:") HWR_LOGGER.info(" - Python %s on %s" % (platform.python_version(), platform.system())) HWR_LOGGER.info(" - Qt %s - %s %s" % ( "%d.%d.%d" % tuple(qt_import.qt_version_no), qt_import.qt_variant, "%d.%d.%d" % tuple(qt_import.pyqt_version_no), )) if qt_import.mpl_imported: HWR_LOGGER.info(" - Matplotlib %s" % "%d.%d.%d" % tuple(qt_import.mpl_version_no)) else: HWR_LOGGER.info(" - Matplotlib not available") HWR_LOGGER.info( "------------------------------------------------------------------------------" ) qt_import.QApplication.setDesktopSettingsAware(False) main_application.lastWindowClosed.connect(main_application.quit) supervisor = GUISupervisor( design_mode=opts.designMode, show_maximized=opts.showMaximized, no_border=opts.noBorder, ) supervisor.set_user_file_directory(user_file_dir) # post event for GUI creation main_application.postEvent(supervisor, MyCustomEvent(LOAD_GUI_EVENT, gui_config_path)) # redirect errors to logger error_handler.enable_std_err_redirection() gevent_timer = qt_import.QTimer() gevent_timer.timeout.connect(do_gevent) gevent_timer.start(0) palette = main_application.palette() palette.setColor(qt_import.QPalette.ToolTipBase, qt_import.QColor(255, 241, 204)) palette.setColor(qt_import.QPalette.ToolTipText, qt_import.Qt.black) main_application.setPalette(palette) main_application.setOrganizationName("MXCuBE") main_application.setOrganizationDomain("https://github.com/mxcube") main_application.setApplicationName("MXCuBE") # app.setWindowIcon(qt_import.QIcon("images/icon.png")) main_application.exec_() supervisor.finalize() if log_lockfile is not None: filename = log_lockfile.name try: log_lockfile.close() os.unlink(filename) except BaseException: logging.getLogger().exception("Problem removing the log lock file") return main_application
class ResolutionBrick(BaseWidget): STATE_COLORS = ( colors.LIGHT_RED, colors.LIGHT_RED, colors.LIGHT_GREEN, colors.LIGHT_YELLOW, colors.LIGHT_YELLOW, colors.LIGHT_YELLOW, qt_import.QColor(255, 165, 0), colors.LIGHT_RED, ) def __init__(self, *args): BaseWidget.__init__(self, *args) # Internal values ----------------------------------------------------- self.resolution_limits = None self.detector_distance_limits = None self.door_interlocked = True # Properties ---------------------------------------------------------- self.add_property("defaultMode", "combo", ("Ang", "mm"), "Ang") self.add_property("mmFormatString", "formatString", "###.##") self.add_property("angFormatString", "formatString", "##.###") self.group_box = qt_import.QGroupBox("Resolution", self) current_label = qt_import.QLabel("Current:", self.group_box) current_label.setFixedWidth(75) self.resolution_ledit = qt_import.QLineEdit(self.group_box) self.resolution_ledit.setReadOnly(True) self.detector_distance_ledit = qt_import.QLineEdit(self.group_box) self.detector_distance_ledit.setReadOnly(True) _new_value_widget = qt_import.QWidget(self) set_to_label = qt_import.QLabel("Set to:", self.group_box) self.new_value_ledit = qt_import.QLineEdit(self.group_box) self.units_combobox = qt_import.QComboBox(_new_value_widget) self.stop_button = qt_import.QPushButton(_new_value_widget) self.stop_button.setIcon(icons.load_icon("Stop2")) self.stop_button.setEnabled(False) self.stop_button.setFixedWidth(25) # Layout -------------------------------------------------------------- _new_value_widget_hlayout = qt_import.QHBoxLayout(_new_value_widget) _new_value_widget_hlayout.addWidget(self.new_value_ledit) _new_value_widget_hlayout.addWidget(self.units_combobox) _new_value_widget_hlayout.addWidget(self.stop_button) _new_value_widget_hlayout.setSpacing(0) _new_value_widget_hlayout.setContentsMargins(0, 0, 0, 0) _group_box_gridlayout = qt_import.QGridLayout(self.group_box) _group_box_gridlayout.addWidget(current_label, 0, 0, 2, 1) _group_box_gridlayout.addWidget(self.resolution_ledit, 0, 1) _group_box_gridlayout.addWidget(self.detector_distance_ledit, 1, 1) _group_box_gridlayout.addWidget(set_to_label, 2, 0) _group_box_gridlayout.addWidget(_new_value_widget, 2, 1) _group_box_gridlayout.setSpacing(0) _group_box_gridlayout.setContentsMargins(1, 1, 1, 1) _main_vlayout = qt_import.QVBoxLayout(self) _main_vlayout.setSpacing(0) _main_vlayout.setContentsMargins(0, 0, 2, 2) _main_vlayout.addWidget(self.group_box) # SizePolicies -------------------------------------------------------- # Qt signal/slot connections ------------------------------------------ self.new_value_ledit.returnPressed.connect(self.current_value_changed) self.new_value_ledit.textChanged.connect(self.input_field_changed) self.units_combobox.activated.connect(self.unit_changed) self.stop_button.clicked.connect(self.stop_clicked) # Other --------------------------------------------------------------- colors.set_widget_color(self.new_value_ledit, colors.LINE_EDIT_ACTIVE, qt_import.QPalette.Base) self.new_value_validator = qt_import.QDoubleValidator( 0, 15, 4, self.new_value_ledit) self.units_combobox.addItem(chr(197)) self.units_combobox.addItem("mm") self.instance_synchronize( "group_box", "resolution_ledit", "detector_distance_ledit", "new_value_ledit", "units_combobox", ) def run(self): if HWR.beamline.detector.distance is not None: self.connect(HWR.beamline.detector.distance, "deviceReady", self.detector_distance_ready) self.connect( HWR.beamline.detector.distance, "deviceNotReady", self.detector_distance_not_ready, ) self.connect( HWR.beamline.detector.distance, "stateChanged", self.detector_distance_state_changed, ) self.connect(HWR.beamline.detector.distance, "valueChanged", self.detector_distance_changed) self.connect( HWR.beamline.detector.distance, "limitsChanged", self.detector_distance_limits_changed, ) if HWR.beamline.detector.distance.is_ready(): self.connected() else: self.disconnected() if HWR.beamline.energy is not None: self.connect(HWR.beamline.energy, "energyChanged", self.energy_changed) if HWR.beamline.resolution is not None: self.connect(HWR.beamline.resolution, "deviceReady", self.resolution_ready) self.connect(HWR.beamline.resolution, "deviceNotReady", self.resolution_not_ready) self.connect(HWR.beamline.resolution, "stateChanged", self.resolution_state_changed) self.connect(HWR.beamline.resolution, "valueChanged", self.resolution_value_changed) self.connect(HWR.beamline.resolution, "limitsChanged", self.resolution_limits_changed) if HWR.beamline.resolution.is_ready(): self.connected() else: self.disconnected() self.update_gui() if HWR.beamline.hutch_interlock is not None: self.connect( HWR.beamline.hutch_interlock, "doorInterlockStateChanged", self.door_interlock_state_changed, ) self.update_gui() def input_field_changed(self, input_field_text): if (self.new_value_validator.validate( input_field_text, 0)[0] == qt_import.QValidator.Acceptable): colors.set_widget_color(self.new_value_ledit, colors.LINE_EDIT_CHANGED, qt_import.QPalette.Base) else: colors.set_widget_color(self.new_value_ledit, colors.LINE_EDIT_ERROR, qt_import.QPalette.Base) def current_value_changed(self): input_field_text = self.new_value_ledit.text() if (self.new_value_validator.validate( input_field_text, 0)[0] == qt_import.QValidator.Acceptable): unit = self.units_combobox.currentText() self.new_value_ledit.setText("") if unit == chr(197): self.set_resolution(float(input_field_text)) elif unit == "mm": self.set_detector_distance(float(input_field_text)) colors.set_widget_color(self.new_value_ledit, colors.LINE_EDIT_ACTIVE, qt_import.QPalette.Base) def connected(self): self.setEnabled(True) def disconnected(self): self.setEnabled(False) def detector_distance_limits_changed(self, limits): if limits: self.detector_distance_limits = limits self.update_gui() def resolution_limits_changed(self, limits): if limits: self.resolution_limits = limits self.update_gui() def create_tool_tip(self): tool_tip = "" if self.units_combobox.currentText() == "mm": if self.detector_distance_limits: tool_tip = "Detector distance limits %0.4f : %0.4f mm" % ( self.detector_distance_limits[0], self.detector_distance_limits[1], ) elif self.resolution_limits: tool_tip = "Resolution limits %0.4f : %0.4f %s" % ( self.resolution_limits[0], self.resolution_limits[1], chr(197), ) if not self.door_interlocked: tool_tip = "\n\nMove resolution command disabled." tool_tip += "\nLock the hutch doors to enable." self.new_value_ledit.setToolTip(tool_tip) def unit_changed(self, unit_index): self.update_gui() self.new_value_ledit.blockSignals(True) self.new_value_ledit.setText("") self.new_value_ledit.blockSignals(False) def update_gui(self, resolution_ready=None, detector_distance_ready=None): """ Door interlock is optional, because not all sites might have it """ groupbox_title = "" detector_distance = HWR.beamline.detector.distance if detector_distance is None: detector_distance_ready = False elif detector_distance_ready is None: detector_distance_ready = detector_distance.is_ready() if detector_distance_ready: self.get_detector_distance_limits() curr_detector_distance = detector_distance.get_value() self.detector_distance_changed(curr_detector_distance) self.detector_distance_state_changed(detector_distance.get_state()) if self.units_combobox.currentText() == "mm": groupbox_title = "Detector distance" self.new_value_validator.setRange( self.detector_distance_limits[0], self.detector_distance_limits[1], 2, ) else: self.detector_distance_state_changed(None) if HWR.beamline.resolution is None: resolution_ready = False elif resolution_ready is None: resolution_ready = HWR.beamline.resolution.is_ready() if resolution_ready: self.get_resolution_limits() curr_resolution = HWR.beamline.resolution.get_value() self.resolution_value_changed(curr_resolution) self.resolution_state_changed(HWR.beamline.resolution.get_state()) if self.units_combobox.currentText() != "mm": groupbox_title = "Resolution" self.new_value_validator.setRange(self.resolution_limits[0], self.resolution_limits[1], 3) else: self.resolution_state_changed(None) self.setEnabled(self.door_interlocked) if not self.door_interlocked: groupbox_title += " (door is unlocked)" self.group_box.setTitle(groupbox_title) self.create_tool_tip() def resolution_ready(self): self.update_gui(resolution_ready=True) def resolution_not_ready(self): self.update_gui(resolution_ready=False) def detector_distance_ready(self): self.update_gui(detector_distance_ready=True) def detector_distance_not_ready(self): self.update_gui(detector_distance_ready=False) def set_resolution(self, value): if self.resolution_limits is not None: if self.resolution_limits[0] < value < self.resolution_limits[1]: HWR.beamline.resolution.set_value(value) def set_detector_distance(self, value): if self.detector_distance_limits is not None: if (self.detector_distance_limits[0] < value < self.detector_distance_limits[1]): HWR.beamline.detector.distance.set_value(value) def energy_changed(self, energy_kev, energy_wavelength): self.get_resolution_limits(True) def get_resolution_limits(self, force=False, resolution_ready=None): if self.resolution_limits is not None and force is False: return if resolution_ready is None: resolution_ready = False if HWR.beamline.resolution is not None: resolution_ready = HWR.beamline.resolution.is_ready() if resolution_ready: self.resolution_limits_changed( HWR.beamline.resolution.get_limits()) else: self.resolution_limits = None def get_detector_distance_limits(self, force=False): if self.detector_distance_limits is not None and force is False: return detector_distance_ready = False detector_distance = HWR.beamline.detector.distance if detector_distance is not None: detector_distance_ready = detector_distance.is_ready() if detector_distance_ready: self.detector_distance_limits_changed( detector_distance.get_limits()) else: self.detector_distance_limits = None def resolution_value_changed(self, value): if value: resolution_str = self["angFormatString"] % float(value) self.resolution_ledit.setText("%s %s" % (resolution_str, u"\u212B")) def detector_distance_changed(self, value): if value: detector_str = self["mmFormatString"] % value self.detector_distance_ledit.setText("%s mm" % detector_str) def resolution_state_changed(self, state): detector_distance = HWR.beamline.detector.distance if detector_distance is not None: if state: color = ResolutionBrick.STATE_COLORS[state.value] else: color = colors.LIGHT_RED unit = self.units_combobox.currentText() if unit is chr(197): if state == detector_distance.STATES.READY: self.new_value_ledit.blockSignals(True) self.new_value_ledit.setText("") self.new_value_ledit.blockSignals(False) self.new_value_ledit.setEnabled(True) else: self.new_value_ledit.setEnabled(False) # or state == detector_distance.motor_states.MOVESTARTED: if state == detector_distance.STATES.BUSY: self.stop_button.setEnabled(True) else: self.stop_button.setEnabled(False) colors.set_widget_color(self.new_value_ledit, color) def detector_distance_state_changed(self, state): if state is None: return detector_distance = HWR.beamline.detector.distance color = ResolutionBrick.STATE_COLORS[state.value] unit = self.units_combobox.currentText() if state == detector_distance.STATES.FAULT: self.setEnabled(False) return if unit == "mm": if state == detector_distance.STATES.READY: self.new_value_ledit.blockSignals(True) self.new_value_ledit.setText("") self.new_value_ledit.blockSignals(False) self.new_value_ledit.setEnabled(True) else: self.new_value_ledit.setEnabled(False) if state == detector_distance.STATES.BUSY: # or \ # state == detector_distance.motor_states.MOVESTARTED: self.stop_button.setEnabled(True) else: self.stop_button.setEnabled(False) colors.set_widget_color(self.new_value_ledit, color) def stop_clicked(self): unit = self.units_combobox.currentText() if unit == chr(197): HWR.beamline.resolution.stop() elif unit == "mm": HWR.beamline.detector.distance.stop() def door_interlock_state_changed(self, state, state_message): self.door_interlocked = state in ["locked_active", "locked_inactive"] self.update_gui()
def setBackgroundColor(self, color): self._bar._background_color = qt_import.QColor(color) self._bar.update()
class QueueItem(qt_import.QTreeWidgetItem): """ Use this class to create a new type of item for the collect tree/queue. """ normal_brush = qt_import.QBrush(qt_import.Qt.black) highlighted_brush = qt_import.QBrush(qt_import.QColor(128, 128, 128)) normal_pen = qt_import.QPen(qt_import.Qt.black) highlighted_pen = qt_import.QPen(qt_import.QColor(128, 128, 128)) bg_brush = qt_import.QBrush(qt_import.QColor(0, 128, 0)) bg_normal_brush = qt_import.QBrush(qt_import.Qt.white) def __init__(self, *args, **kwargs): qt_import.QTreeWidgetItem.__init__(self, args[0]) self.deletable = kwargs.pop("deletable", False) self.pen = QueueItem.normal_pen self.brush = QueueItem.normal_brush self.bg_brush = QueueItem.bg_normal_brush self.previous_bg_brush = QueueItem.bg_normal_brush self._queue_entry = None self._data_model = None self._checkable = True self._previous_check_state = False self._font_is_bold = False self._star = False self._base_tool_tip = "" self.setText(1, "") def listView(self): # remove this return self.treeWidget() def setOn(self, state): """ Backward compatability, because QueueManager and other hwobj are using this method to change state """ if self._checkable: if state: check_state = qt_import.Qt.Checked else: check_state = qt_import.Qt.Unchecked self.setCheckState(0, check_state) else: self.setCheckState(0, qt_import.Qt.Unchecked) def setCheckState(self, column, check_state): """ sets check state for item and all children and parent if they exist """ self._previous_check_state = self.checkState(0) if isinstance(self, DataCollectionGroupQueueItem): self._checkable = False if self.childCount() == 0: self._checkable = True else: for index in range(self.childCount()): if self.child(index)._checkable: self._checkable = True break self.parent().setCheckState(column, check_state) if not self._checkable: check_state = qt_import.Qt.Unchecked qt_import.QTreeWidgetItem.setCheckState(self, column, check_state) if self._queue_entry: self._queue_entry.set_enabled(check_state > 0) if self._data_model: self._data_model.set_enabled(check_state > 0) def set_hidden(self, hidden): self.setHidden(hidden) for index in range(self.childCount()): self.child(index).setHidden(hidden) if self._queue_entry: self._queue_entry.set_enabled(not hidden) if self._data_model: self._data_model.set_enabled(not hidden) def update_check_state(self, new_state): """ in qt3 method was called stateChanged. """ if new_state != self._previous_check_state: self.setCheckState(0, self.checkState(0)) if isinstance(self, DataCollectionGroupQueueItem): for index in range(self.childCount()): self.child(index).setCheckState(0, self.checkState(0)) def move_item(self, after): self.parent().takeChild(self.parent().indexOfChild(self)) after.parent().insertChild(after.parent().indexOfChild(after) + 1, self) container_qe = self.get_queue_entry().get_container() after_qe = after.get_queue_entry() container_qe.swap(after_qe, self.get_queue_entry()) def setHighlighted(self, enable): """ Controls highlighting of the list item. :param enable: Highlighted True, or not highlighted False. :type enable: bool """ if enable: self.pen = QueueItem.highlighted_pen self.brush = QueueItem.highlighted_brush else: self.pen = QueueItem.normal_pen self.brush = QueueItem.normal_brush if self.treeWidget(): self.treeWidget().updateGeometry() def set_background_color(self, color_index): self.previous_bg_brush = self.background(0) color = colors.QUEUE_ENTRY_COLORS[color_index] self.bg_brush = qt_import.QBrush(color) self.setBackground(0, self.bg_brush) self.setBackground(1, self.bg_brush) def restoreBackgroundColor(self): self.bg_brush = self.previous_bg_brush self.setBackground(0, self.bg_brush) self.setBackground(1, self.bg_brush) def setFontBold(self, state): self._font_is_bold = state def reset_style(self): self.set_background_color(0) self.setFontBold(False) self.setHighlighted(False) def lastItem(self): """ :returns: The last item of this child. :rtype: QueueItem """ if self.childCount() > 0: return self.child(self.childCount()) def set_checkable(self, state): self._checkable = state def set_queue_entry(self, queue_entry): self._queue_entry = queue_entry def get_previous_check_state(self): return self._previous_check_state def get_queue_entry(self): return self._queue_entry def get_model(self): return self._data_model def update_display_name(self): self.setText(0, self._data_model.get_display_name()) def update_tool_tip(self): pass def set_star(self, state): self._star = state def has_star(self): return self._star == True def get_all_grand_children(self): grand_children_list = [] for child_index in range(self.childCount()): for grand_child_index in range( self.child(child_index).childCount()): grand_children_list.append( self.child(child_index).child(grand_child_index)) return grand_children_list def set_strike_out(self, state): font = self.font(0) font.setStrikeOut(state) self.setFont(0, font)