def setReadOnly(self, ro): pal = QtGui.QPalette() if ro: pal.setColor(QtGui.QPalette.Base, QtGui.QColor('lightgrey')) self.setPalette(pal) super(NotesTextEdit, self).setReadOnly(ro)
def paint(self, painter, option, index): node = index.internalPointer() option = QtWidgets.QStyleOptionViewItem(option) self.initStyleOption(option, index) if (option.state & QtWidgets.QStyle.State_Selected and isinstance(node, (ctm.DeviceNode, htm.DeviceNode)) and self.director.linked_mode): device = node.ref color = None if device.idc_conflict or device.address_conflict: color = QtGui.QColor('darkRed') elif device.has_hw and device.has_cfg: if device.hw.is_connected(): if device.config_applied is True: color = QtGui.QColor('darkGreen') elif device.config_applied is False: color = QtGui.QColor('darkOrange') # else config_applied should be None meaning "unknown" if color is not None: option.palette.setColor(QtGui.QPalette.Highlight, color) super(MCTreeItemDelegate, self).paint(painter, option, index)
def __init__(self, serial_ports_usb, serial_ports_serial, urls_in_use=list(), url=None, do_connect_default=True, autoconnect_default=True, title="Add MRC", parent=None): super(AddMRCDialog, self).__init__(parent) self.urls_in_use = urls_in_use self.ui = util.loadUi(":/ui/connect_dialog.ui") layout = QtWidgets.QHBoxLayout(self) layout.addWidget(self.ui) self.setWindowTitle(title) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Ok).setEnabled(False) self.ui.accepted.connect(self.accept) self.ui.rejected.connect(self.reject) for combo in (self.ui.combo_serial_port_usb, self.ui.combo_serial_port_serial): combo.setValidator( QtGui.QRegExpValidator(QtCore.QRegExp('.+'), None)) self.ui.le_tcp_host.setValidator( QtGui.QRegExpValidator(QtCore.QRegExp('.+'), None)) self.ui.le_mesycontrol_host.setValidator( QtGui.QRegExpValidator(QtCore.QRegExp('.+'), None)) self.ui.le_tcp_host.setText('localhost') self.ui.le_mesycontrol_host.setText('localhost') self.ui.cb_connect.setChecked(do_connect_default) self.ui.cb_autoconnect.setChecked(autoconnect_default) for port in serial_ports_usb: self.ui.combo_serial_port_usb.addItem(port) for port in serial_ports_serial: self.ui.combo_serial_port_serial.addItem(port) for le in self.ui.findChildren(QtWidgets.QLineEdit): le.textChanged.connect(self._validate_inputs) for combo in self.ui.findChildren(QtWidgets.QComboBox): combo.currentIndexChanged.connect(self._validate_inputs) combo.editTextChanged.connect(self._validate_inputs) for spin in self.ui.findChildren(QtWidgets.QSpinBox): spin.valueChanged.connect(self._validate_inputs) self.ui.stacked_widget.currentChanged.connect(self._validate_inputs) self._validate_inputs() self._result = None if url is not None: self._set_url(url)
def data(self, column, role): mrc = self.ref if not mrc: return None if column == 0 and role == Qt.DisplayRole: ret = mrc.get_display_url() if mrc.hw is not None and mrc.hw.is_silenced(): ret += " (silenced)" if mrc.hw is not None and not mrc.hw.has_write_access(): ret += " (read-only)" return ret if column == 0: if mrc.hw is not None and not mrc.hw.is_connected() and mrc.hw.last_connection_error is not None: if role == Qt.DecorationRole: return QtGui.QPixmap(":/warning.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "%s: %s" % (mrc.get_display_url(), mrc.hw.last_connection_error) elif mrc.hw is not None and mrc.hw.is_connecting(): if role == Qt.DecorationRole: return QtGui.QPixmap(":/connecting.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Connecting to %s" % (mrc.get_display_url(),) elif mrc.hw is None or mrc.hw.is_disconnected(): if role == Qt.DecorationRole: return QtGui.QPixmap(":/disconnected.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Disconnected from %s" % (mrc.get_display_url(),) elif mrc.hw is not None and mrc.hw.is_connected() and any(d.address_conflict for d in mrc.hw): if role == Qt.DecorationRole: return QtGui.QPixmap(":/warning.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Address conflict detected" elif mrc.hw is not None and mrc.hw.is_connected(): if role == Qt.DecorationRole: return QtGui.QPixmap(":/connected.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Connected to %s" % mrc.get_display_url()
def _get_palette_old(self, rf): pal = QtGui.QPalette(self._original_palette) try: result = rf.result() if isinstance(result, bm.SetResult) and not result: raise RuntimeError() except Exception: pal.setColor(QtGui.QPalette.Base, QtGui.QColor('red')) log.debug("_get_palette: Exception from result future; setting red background color") return pal if (self.write_mode == util.COMBINED and self.device.has_hw and self.device.has_cfg and self.profile is not None and self.get_write_profile().should_be_stored()): try: log.debug("_get_palette: comparing hardware and config") f_cfg = self.device.cfg.get_parameter(self.write_address) f_hw = self.device.hw.get_parameter(self.read_address) if not f_cfg.done(): log.debug("_get_palette: adding update callback to config future") f_cfg.add_done_callback(self._update_wrapper) if not f_hw.done(): log.debug("_get_palette: adding update callback to hardware future") f_hw.add_done_callback(self._update_wrapper) if f_cfg.done() and f_hw.done(): cfg_value = int(f_cfg) hw_value = int(f_hw) log.debug("_get_palette: both cfg and hw futures are done; ra=%d, wa=%d, cfg_value=%d, hw_value=%d", self.read_address, self.write_address, cfg_value, hw_value) if cfg_value != hw_value: log.debug("_get_palette: ra=%d, wa=%d, cfg and hw differ; returning orange", self.read_address, self.write_address) pal.setColor(QtGui.QPalette.Base, QtGui.QColor('orange')) except (future.IncompleteFuture, KeyError, util.SocketError, util.Disconnected): log.exception("_get_palette") else: log.debug("_get_palette: hw vs cfg condition failed; returning original palette") return pal
def __init__(self, gui_app, parent=None): super(TutorialWidget, self).__init__(parent) self.gui_app = gui_app #self.setStyleSheet('background: lightyellow;') self.text_doc = QtGui.QTextDocument(self) f = QtCore.QFile(":/quickstart.html") if f.open(QtCore.QIODevice.ReadOnly): s = QtCore.QTextStream(f) html = s.readAll() else: html = "quickstart.html not found!" self.text_doc.setHtml(html) self.text_browser = TutorialTextBrowser(openLinks=False) self.text_browser.setDocument(self.text_doc) self.text_browser.href_hover.connect(self._on_href_hover) layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.text_browser) self.flasher = UIFlasher(widget=self)
def make_title_label(title): title_font = QtGui.QFont() title_font.setBold(True) label = QtWidgets.QLabel(title) label.setFont(title_font) label.setAlignment(Qt.AlignCenter) return label
def _get_palette(self, rf): pal = QtGui.QPalette(self._original_palette) try: result = rf.result() if isinstance(result, bm.SetResult) and not result: raise RuntimeError() except Exception: pal.setColor(QtGui.QPalette.Base, QtGui.QColor('red')) log.debug("_get_palette: Exception from result future; setting red background color") return future.Future().set_result(pal) ret = future.Future() if (self.write_mode == util.COMBINED and self.device.has_hw and self.device.has_cfg and self.profile is not None and self.get_write_profile().should_be_stored()): try: f_cfg = self.device.cfg.get_parameter(self.write_address) f_hw = self.device.hw.get_parameter(self.read_address) f_params = self.device.get_config_parameters() def all_done(_): has_param = any(pp.address in (self.write_address, self.read_address) for pp in f_params.result()) if has_param: cfg_value = int(f_cfg) hw_value = int(f_hw) if cfg_value != hw_value: log.debug("_get_palette: ra=%d, wa=%d, cfg and hw differ; returning orange", self.read_address, self.write_address) pal.setColor(QtGui.QPalette.Base, QtGui.QColor('orange')) ret.set_result(pal) future.all_done(f_cfg, f_hw, f_params).add_done_callback(all_done) return ret except (future.IncompleteFuture, KeyError, util.SocketError, util.Disconnected): pass return ret.set_result(pal)
def handle_exception(self, exc_type, exc_value, exc_trace): with QtCore.QMutexLocker(self._mutex): try: self.setTextColor(QtGui.QColor("#ff0000")) lines = exc_value.traceback_lines self.append("".join(lines).strip()) except AttributeError: self.append("".join(traceback.format_exception(exc_type, exc_value, exc_trace)).strip()) finally: self.setTextColor(self._original_text_color)
def handle_log_record(self, log_record): with QtCore.QMutexLocker(self._mutex): try: if log_record.levelno >= logging.ERROR: self.setTextColor(QtGui.QColor("#ff0000")) self.append(self.err_fmt.format(log_record), prepend_time=False) else: self.append(self.fmt.format(log_record), prepend_time=False) finally: self.setTextColor(self._original_text_color)
def __init__(self, **kwargs): super(DefaultParameterBinding, self).__init__(**kwargs) log.info("DefaultParameterBinding: target=%s", self.target) if isinstance(self.target, QtWidgets.QWidget): self._original_palette = QtGui.QPalette(self.target.palette()) else: self._original_palette = None log.info("DefaultParameterBinding: non QWidget target %s", self.target)
def data(self, column, role): if column == 0 and role == Qt.DisplayRole: return str(self.bus_number) if column == 0 and role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Bus %d" % self.bus_number if column == 0 and role == Qt.DecorationRole: mrc = self.parent.ref.hw if mrc is not None and any(d.address_conflict for d in mrc.get_devices(self.bus_number)): return QtGui.QPixmap(":/warning.png")
def all_done(_): has_param = any(pp.address in (self.write_address, self.read_address) for pp in f_params.result()) if has_param: cfg_value = int(f_cfg) hw_value = int(f_hw) if cfg_value != hw_value: log.debug("_get_palette: ra=%d, wa=%d, cfg and hw differ; returning orange", self.read_address, self.write_address) pal.setColor(QtGui.QPalette.Base, QtGui.QColor('orange')) ret.set_result(pal)
def make_apply_common_button_layout(input_spinbox, tooltip, on_clicked): # Wrapper to invoke the clicked handler without the boolean arg that's # passed from QPushButton.clicked(). def _on_clicked(): on_clicked() button = QtWidgets.QPushButton(clicked=_on_clicked) button.setIcon(QtGui.QIcon(":/arrow-bottom.png")) button.setMaximumHeight(input_spinbox.sizeHint().height()) button.setMaximumWidth(16) button.setToolTip(tooltip) layout = QtWidgets.QHBoxLayout() layout.addWidget(input_spinbox) layout.addWidget(button) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(1) return (layout, button)
def __init__(self, bus=None, available_addresses=bm.ALL_DEVICE_ADDRESSES, known_idcs=list(), allow_custom_idcs=True, title="Add Device", selected_bus=None, selected_address=None, selected_idc=None, assigned_name=None, parent=None): """ Dialog constructor. If `bus' is given the dialog will use it as the selected bus and won't allow the user to change the bus. `available_addresses` should be a list of (bus, address) pairs. These address pairs will be available for the user to choose from. `known_idcs` should be a list of (idc, name) pairs. If `allow_custom_idcs` is True the user may enter a custom IDC, otherwise only IDCs from `known_idcs` are selectable. If `known_idcs' is empty and `allow_custom_idcs' is False this method will raise an exception. If `selected_bus` and `selected_address` is not None the corresponding item will be preselected in the GUI. If `selected_idc` is not None the device type will be set using the given IDC and will not be modifyable. """ if len(known_idcs) == 0 and not allow_custom_idcs: raise RuntimeError("No devices to choose from") if len(available_addresses) == 0 or ( bus is not None and util.ilen_destructive( filter(lambda x: x[0] == bus, available_addresses)) == 0): raise RuntimeError("No addresses available") super(AddDeviceDialog, self).__init__(parent) self.log = util.make_logging_source_adapter(__name__, self) self.setWindowTitle(title) self._result = None self.allow_custom_idcs = allow_custom_idcs self.bus_combo = QtWidgets.QComboBox() self.bus_combo.addItems([str(i) for i in bm.BUS_RANGE]) self.address_combos = [QtWidgets.QComboBox() for i in bm.BUS_RANGE] for b, a in sorted(available_addresses): self.address_combos[b].addItem("%X" % a, a) self.address_combo_stack = QtWidgets.QStackedWidget() for combo in self.address_combos: self.address_combo_stack.addWidget(combo) self.bus_combo.activated.connect( self.address_combo_stack.setCurrentIndex) self.idc_combo = EatReturnCombo() for idc, name in sorted(known_idcs, key=lambda x: x[1]): self.idc_combo.addItem("%s (%d)" % (name, idc), idc) if self.idc_combo.findData(idc) < 0: self.idc_combo.addItem(str(idc), idc) if selected_idc is not None: self.log.debug("selected_idc=%d, idx=%d", selected_idc, self.idc_combo.findData(selected_idc)) self.idc_combo.setCurrentIndex( self.idc_combo.findData(selected_idc)) self.idc_combo.setEnabled(False) if bus is not None: self.bus_combo.setCurrentIndex(bus) self.address_combo_stack.setCurrentIndex(bus) self.name_input = QtWidgets.QLineEdit() if assigned_name is not None: self.name_input.setText(assigned_name) self.button_box = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) if allow_custom_idcs: self.idc_combo.setEditable(True) self.idc_combo.setValidator(QtGui.QIntValidator(1, 99)) ok_button = self.button_box.button(QtWidgets.QDialogButtonBox.Ok) ok_button.setEnabled(len(known_idcs)) def combo_index_changed(): ok_button.setEnabled(True) def combo_le_text_edited(): ok_button.setEnabled( self.idc_combo.lineEdit().hasAcceptableInput()) self.idc_combo.currentIndexChanged.connect(combo_index_changed) self.idc_combo.lineEdit().textEdited.connect(combo_le_text_edited) if selected_bus is not None: assert selected_bus in bm.BUS_RANGE self.bus_combo.setCurrentIndex(selected_bus) self.address_combo_stack.setCurrentIndex(selected_bus) if selected_address is not None: assert selected_address in bm.DEV_RANGE combo = self.address_combo_stack.currentWidget() combo.setCurrentIndex(combo.findText("%X" % selected_address)) def accept(): bus = self.bus_combo.currentIndex() address = int(self.address_combos[bus].itemData( self.address_combos[bus].currentIndex())) if self.allow_custom_idcs and self.idc_combo.lineEdit( ).hasAcceptableInput(): idc = int(self.idc_combo.lineEdit().text()) else: idx = self.idc_combo.currentIndex() idc = int(self.idc_combo.itemData(idx)) name = self.name_input.text() self._result = AddDeviceDialog.Result(bus, address, idc, name) super(AddDeviceDialog, self).accept() self.button_box.accepted.connect(accept) self.button_box.rejected.connect(self.reject) layout = QtWidgets.QFormLayout(self) layout.addRow("Bus", self.bus_combo) layout.addRow("Address", self.address_combo_stack) layout.addRow("IDC", self.idc_combo) layout.addRow("Name", self.name_input) layout.addRow(self.button_box)
def data(self, column, role): device = self.ref # app_model.Device hw = device.hw # hardware_model.Device cfg = device.cfg # config_model.Device if column == 0 and role == Qt.DisplayRole: if cfg is None: return "%X <not present in setup>" % device.address try: type_name = self.model.device_registry.get_device_name(cfg.idc) except KeyError: type_name = "idc=%d" % cfg.idc if len(cfg.name): data = "%s (%s)" % (cfg.name, type_name) else: data = type_name if cfg.modified: data += "*" return "%X %s" % (device.address, data) if column == 0 and role == Qt.EditRole: return self.ref.cfg.name if column == 0: if hw is not None and cfg is not None and self.model.linked_mode and hw.address_conflict: if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Address conflict" if hw is not None and self.model.linked_mode and device.idc_conflict: if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "IDC conflict" if self.model.linked_mode and device.has_hw and device.has_cfg and device.hw.is_connected( ): if role in (Qt.ToolTipRole, Qt.StatusTipRole): if device.config_applied is True: return "Hardware matches config" elif device.config_applied is False: return "Hardware and config differ" if cfg is not None and role in (Qt.ToolTipRole, Qt.StatusTipRole): data = str() if len(cfg.name): data += cfg.name + " " type_name = self.model.device_registry.get_device_name(cfg.idc) data += "%s (idc=%d)" % (type_name, cfg.idc) if cfg.modified: data += " (modified)" return data if role == Qt.BackgroundRole and self.model.linked_mode: if device.idc_conflict or device.address_conflict: return QtGui.QColor('red') if device.has_hw and device.has_cfg: if device.hw.is_connected(): if device.config_applied is True: return QtGui.QColor('green') if device.config_applied is False: return QtGui.QColor('orange')
def data(self, column, role): device = self.ref # app_model.Device hw = device.hw # hardware_model.Device mrc = device.mrc # app_model.MRC if column == 0 and role == Qt.DisplayRole: if mrc.hw is None or not mrc.hw.is_connected(): return "%X <no mrc connection>" % device.address elif hw is None: return "%X <device not connected>" % device.address try: name = self.model.device_registry.get_device_name(hw.idc) data = "%s" % name except KeyError: name = None data = "idc=%d" % hw.idc return "%X %s" % (device.address, data) if column == COL_RC and hw is not None and mrc.hw.is_connected(): if role == Qt.DisplayRole: return "RC on" if hw.rc else "RC off" if role == Qt.EditRole: return hw.rc if column == 0: if hw is not None and hw.address_conflict: if role == Qt.DecorationRole: return QtGui.QPixmap(":/warning.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Address conflict" if hw is not None and self.model.linked_mode and device.idc_conflict: if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "IDC conflict" if self.model.linked_mode and device.has_hw and device.has_cfg and device.hw.is_connected(): if role in (Qt.ToolTipRole, Qt.StatusTipRole): if device.config_applied is True: return "Hardware matches config" elif device.config_applied is False: return "Hardware and config differ" if mrc.hw is None or mrc.hw.is_disconnected(): if role == Qt.DecorationRole: return QtGui.QPixmap(":/disconnected.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Disconnected from %s" % (mrc.get_display_url(),) if mrc.hw is not None and mrc.hw.is_connecting(): if role == Qt.DecorationRole: return QtGui.QPixmap(":/connecting.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "Connecting to %s" % (mrc.get_display_url(),) if mrc.hw is not None and mrc.hw.is_connected() and not hw: if role == Qt.DecorationRole: return QtGui.QPixmap(":/disconnected.png") if mrc.hw is not None and not mrc.hw.is_connected() and mrc.hw.last_connection_error is not None: if role == Qt.DecorationRole: return QtGui.QPixmap(":/warning.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "%s: %s" % (mrc.get_display_url(), mrc.hw.last_connection_error) if mrc.hw is not None and mrc.hw.is_connected() and hw is not None: if role == Qt.DecorationRole: return QtGui.QPixmap(":/connected.png") if role in (Qt.ToolTipRole, Qt.StatusTipRole): return "%s (idc=%d)" % (device.hw_profile.name, hw.idc) if role == Qt.BackgroundRole and self.model.linked_mode: if hw is not None and hw.address_conflict: return QtGui.QColor('red') if device.idc_conflict and self.model.linked_mode: return QtGui.QColor('red') if device.has_hw and device.has_cfg: if device.hw.is_connected(): if device.config_applied is True: return QtGui.QColor('green') if device.config_applied is False: return QtGui.QColor('orange')
def on_actionAbout_triggered(self): try: from . import mc_version version = mc_version.version except ImportError: version = "devel version" d = QtWidgets.QDialog(self) d.setWindowTitle("About mesycontrol") license = QtWidgets.QTextBrowser(parent=d) license.setWindowFlags(Qt.Window) license.setWindowTitle("mesycontrol license") license.setText("") try: f = QtCore.QFile(":/gpl-notice.txt") if not f.open(QtCore.QIODevice.ReadOnly | QtCore.QIODevice.Text): return license.setPlainText(str(f.readAll(), 'utf-8')) finally: f.close() l = QtWidgets.QVBoxLayout(d) logo = QtWidgets.QLabel() logo.setPixmap( QtGui.QPixmap(":/mesytec-logo.png").scaledToWidth( 300, Qt.SmoothTransformation)) l.addWidget(logo) t = "mesycontrol - %s" % version label = QtWidgets.QLabel(t) font = label.font() font.setPointSize(15) font.setBold(True) label.setFont(font) l.addWidget(label) l.addWidget(QtWidgets.QLabel("Remote control for mesytec devices.")) l.addWidget(QtWidgets.QLabel("© 2014-2022 mesytec GmbH & Co. KG")) t = '<a href="mailto:[email protected]">[email protected]</a> - <a href="http://www.mesytec.com">www.mesytec.com</a>' label = QtWidgets.QLabel(t) label.setOpenExternalLinks(True) l.addWidget(label) t = 'Running on Python %s using PySide2 %s with Qt %s.' % ( platform.python_version(), PySide2.__version__, PySide2.QtCore.__version__) l.addWidget(QtWidgets.QLabel(t)) l.addSpacing(20) bl = QtWidgets.QHBoxLayout() def license_button_clicked(): sz = license.size() sz = sz.expandedTo(QtCore.QSize(500, 300)) license.resize(sz) license.show() license.raise_() b = QtWidgets.QPushButton("&License", clicked=license_button_clicked) bl.addWidget(b) b = QtWidgets.QPushButton("&Close", clicked=d.close) b.setAutoDefault(True) b.setDefault(True) bl.addWidget(b) l.addLayout(bl) for item in (l.itemAt(i) for i in range(l.count())): item.setAlignment(Qt.AlignHCenter) w = item.widget() if isinstance(w, QtWidgets.QLabel): w.setTextInteractionFlags(Qt.TextBrowserInteraction) d.exec_()
def test_app_model_using_local_setup(): from mesycontrol import application_registry from mesycontrol import app_model from mesycontrol import config from mesycontrol import hw_model from mesycontrol import mrc_connection from mesycontrol import mrc_controller logging.basicConfig(level=logging.INFO, format='[%(asctime)-15s] [%(name)s.%(levelname)s] %(message)s') signal.signum_to_name = dict((getattr(signal, n), n) for n in dir(signal) if n.startswith('SIG') and '_' not in n) signal.signal(signal.SIGINT, signal_handler) application_registry.instance = application_registry.ApplicationRegistry( sys.executable if getattr(sys, 'frozen', False) else __file__) app = QtGui.QApplication(sys.argv) timer = QtCore.QTimer() timer.timeout.connect(lambda: None) timer.start(500) con = mrc_connection.factory(serial_port='/dev/ttyUSB0', baud_rate=0) mrc_model = hw_model.MRCModel() mrc_model.controller = mrc_controller.MRCController(con, mrc_model) mrc_config = config.MRCConfig() mrc_config.connection_config = config.make_connection_config(con) mrc = app_model.AppMrc(mrc_model=mrc_model, mrc_config=mrc_config) setup = config.Setup() setup.add_mrc_config(mrc_config) def on_mrc_connecting(): print("connecting...") def on_mrc_connected(): print("connected!") def on_mrc_disconnected(info=None): print("disconnected!", info) def on_mrc_ready(): print("MRC is ready!") for device in mrc.get_devices(): print(device, device.model, device.config) print("Saving setup...") def on_device_added(device): print("Device added: %s" % device) mrc.connecting.connect(on_mrc_connecting) mrc.connected.connect(on_mrc_connected) mrc.disconnected.connect(on_mrc_disconnected) mrc.ready.connect(on_mrc_ready) mrc.device_added.connect(on_device_added) mrc.connect() return app.exec_()
def data(self, idx, role=Qt.DisplayRole): if not idx.isValid() or self.device is None: return None row = idx.row() col = idx.column() hw = self.device.hw cfg = self.device.cfg profile = self.profile try: pp = profile[row] # parameter profile except (IndexError, AttributeError): pp = None if role == Qt.DisplayRole: if col == COL_ADDRESS: return row elif col == COL_NAME and pp is not None and pp.is_named(): return pp.name elif col == COL_HW_VALUE: if hw is None: return "<device not present>" if hw.is_disconnected(): return "<not connected>" if hw.is_connecting(): return "<connecting>" if hw.address_conflict: return "<address conflict>" try: value = int(hw.get_parameter(row)) if self.display_hex_values: return "0x{:04x}".format(value) return value except future.IncompleteFuture: return "<reading>" elif col == COL_CFG_VALUE: if pp is None or not pp.should_be_stored(): return None if cfg is None: return "<config not present>" try: value = int(cfg.get_parameter(row)) if self.display_hex_values: return "0x{:04x}".format(value) return value except future.IncompleteFuture: return "<reading>" except KeyError: return "<not set>" elif col in (COL_HW_UNIT_VALUE, COL_CFG_UNIT_VALUE): try: unit = pp.units[1] # skip the 'raw' unit at index 0 except (IndexError, AttributeError): return None if (col == COL_HW_UNIT_VALUE and hw is not None and hw.is_connected() and not hw.address_conflict): try: raw = int(hw.get_parameter(row)) except future.IncompleteFuture: return "<reading>" elif col == COL_CFG_UNIT_VALUE and cfg is not None: if pp is None or not pp.should_be_stored() or cfg is None: return None try: raw = int(cfg.get_parameter(row)) except future.IncompleteFuture: return "<reading>" except KeyError: return None else: return None value = unit.unit_value(raw) return "%f %s" % (value, unit.label) if role == Qt.EditRole: if col == COL_HW_VALUE: # should succeed as otherwise the editable flag would not be set return int(hw.get_parameter(row)) if col == COL_CFG_VALUE: try: # fails if no config exists or the parameter is not set return int(cfg.get_parameter(row)) except (IndexError, AttributeError, KeyError): if pp is not None: return pp.default return 0 if role == Qt.BackgroundRole: if (self.display_mode == util.COMBINED and hw is not None and cfg is not None and pp is not None and pp.should_be_stored()): try: cfg_raw = int(cfg.get_parameter(row)) hw_raw = int(hw.get_parameter(row)) if cfg_raw != hw_raw: return QtGui.QColor('orange') except (future.IncompleteFuture, KeyError, util.SocketError, util.Disconnected): pass if col == COL_HW_VALUE and pp is not None and pp.read_only: return QtGui.QColor("lightgray") if col == COL_CFG_VALUE and pp is not None and not pp.should_be_stored( ): return QtGui.QColor("lightgray") if role in (Qt.ToolTipRole, Qt.StatusTipRole): if pp is not None and pp.read_only: if col == COL_HW_VALUE: return "%s=%s (read_only)" % ( pp.name if pp.is_named() else str(row), self.data(idx, Qt.DisplayRole)) if col == COL_CFG_VALUE: return "%s (read_only)" % (pp.name if pp.is_named() else str(row)) if col == COL_CFG_VALUE and pp is not None and not pp.should_be_stored( ): return "%s (not stored in config)" % (pp.name if pp.is_named() else str(row)) return None
def make_icon(source): return QtGui.QIcon(QtGui.QPixmap(source))
self.append("".join(lines).strip()) except AttributeError: self.append("".join(traceback.format_exception(exc_type, exc_value, exc_trace)).strip()) finally: self.setTextColor(self._original_text_color) def contextMenuEvent(self, event): pos = event.globalPos() menu = self.createStandardContextMenu(pos) menu.addAction("Clear").triggered.connect(self.clear) menu.exec_(pos) if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG, format='[%(asctime)-15s] [%(name)s.%(levelname)s] %(message)s') qapp = QtGui.QApplication(sys.argv) log_view = LogView() log_view.resize(400, 400) log_view.show() qt_logger = util.QtLogEmitter() qt_logger.log_record.connect(log_view.handle_log_record) logging.getLogger().addHandler(qt_logger.get_handler()) logger = logging.getLogger(__name__) def on_button_clicked(): logging.getLogger("testlogger").debug("Hello World!") button = QtWidgets.QPushButton("Log!", clicked=on_button_clicked) button.show()