def update_indents(self): max_widget_height = 0 for visual_index in range(self.count()): logical_index = self.logicalIndex(visual_index) if logical_index in self.widgets: widget = self.widgets[logical_index] if not self.isSectionHidden(logical_index): max_widget_height = max(max_widget_height, widget.size().height()) desired_indent = widget.size().width() item = self.model.horizontalHeaderItem(logical_index) font = item.font() fontmetrics = QtGui.QFontMetrics(font, self) indent = '' while fontmetrics.width(indent) < desired_indent: indent += self.thinspace self.indents[widget] = indent font = self.font() fontmetrics = QtGui.QFontMetrics(font, self) height = fontmetrics.height() required_padding = (max_widget_height + 2 - height) // 2 required_padding = max(required_padding, 3) QtWidgets.QHeaderView.setStyleSheet( self, self.stylesheet % (required_padding, required_padding, self.custom_style))
def on_lock_axes_triggered(self): if self.lock_action.isChecked(): self.lock_axes = True self.lock_action.setIcon(QtGui.QIcon(':qtutils/fugue/lock')) else: self.lock_axes = False self.lock_action.setIcon(QtGui.QIcon(':qtutils/fugue/lock-unlock'))
def status_monitor(self, notify_queue=None): # When called with a queue, this function writes to the queue # when the pulseblaster is waiting. This indicates the end of # an experimental run. self.status, waits_pending, time_based_shot_over = yield ( self.queue_work(self._primary_worker, 'check_status')) if self.programming_scheme == 'pb_start/BRANCH': done_condition = self.status['waiting'] elif self.programming_scheme == 'pb_stop_programming/STOP': done_condition = self.status['stopped'] if time_based_shot_over is not None: done_condition = time_based_shot_over if notify_queue is not None and done_condition and not waits_pending: # Experiment is over. Tell the queue manager about it, then # set the status checking timeout back to every 2 seconds # with no queue. notify_queue.put('done') self.statemachine_timeout_remove(self.status_monitor) self.statemachine_timeout_add(2000, self.status_monitor) if self.programming_scheme == 'pb_stop_programming/STOP': # Not clear that on all models the outputs will be correct after being # stopped this way, so we do program_manual with current values to be sure: self.program_device() # Update widgets with new status for state in self.status_states: if self.status[state]: icon = QtGui.QIcon(':/qtutils/fugue/tick') else: icon = QtGui.QIcon(':/qtutils/fugue/cross') pixmap = icon.pixmap(QtCore.QSize(16, 16)) self.status_widgets[state].setPixmap(pixmap)
def __init__(self, figure, identifier, filepath): self.identifier = identifier loader = UiLoader() self.ui = loader.load(os.path.join(LYSE_DIR, 'plot_window.ui'), PlotWindow(self)) self.set_window_title(identifier, filepath) # figure.tight_layout() self.figure = figure self.canvas = figure.canvas self.navigation_toolbar = NavigationToolbar(self.canvas, self.ui) self.lock_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/lock-unlock'), 'Lock axes', self.on_lock_axes_triggered) self.lock_action.setCheckable(True) self.lock_action.setToolTip('Lock axes') self.copy_to_clipboard_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/clipboard--arrow'), 'Copy to clipboard', self.on_copy_to_clipboard_triggered) self.copy_to_clipboard_action.setToolTip('Copy to clipboard') self.copy_to_clipboard_action.setShortcut(QtGui.QKeySequence.Copy) self.ui.verticalLayout_canvas.addWidget(self.canvas) self.ui.verticalLayout_navigation_toolbar.addWidget( self.navigation_toolbar) self.lock_axes = False self.axis_limits = None self.update_window_size() self.ui.show()
def update_bar_style(self, marker=False, wait=False, previous=False): """Update the bar's style to reflect the next marker or wait, according to self.next_marker_index or self.next_wait_index. If previous=True, instead update to reflect the current marker or wait.""" assert not (marker and wait) # Ignore requests to reflect markers or waits if there are no markers # or waits in this shot: marker = marker and self.markers is not None and len(self.markers) > 0 wait = wait and self.waits is not None and len(self.waits) > 0 if marker: marker_index = self.next_marker_index if previous: marker_index -= 1 assert marker_index >= 0 label, _, color = self.markers[marker_index] self.bar_text_prefix = '[%s] ' % _ensure_str(label) r, g, b = color[0] if color.dtype == np.uint8 and (r, g, b) == (0, 0, 0): # is old colour spec, in which (0,0,0) meant no colour specified. r, g, b = (-1, -1, -1) # (-1,-1,-1) means no colour set for the marker. Don't change the bar colour # in this case. if (r, g, b) != (-1, -1, -1): bar_color = QtGui.QColor(r, g, b) if black_has_good_contrast(r, g, b): highlight_text_color = QtCore.Qt.black else: highlight_text_color = QtCore.Qt.white else: bar_color = None highlight_text_color = None regular_text_color = None # use default elif wait: wait_index = self.next_wait_index if previous: wait_index -= 1 assert wait_index >= 0 label = self.waits[wait_index]['label'] self.bar_text_prefix = '-%s- ' % _ensure_str(label) highlight_text_color = regular_text_color = QtGui.QColor(192, 0, 0) bar_color = QtCore.Qt.gray if marker or wait: palette = self.style.standardPalette() if bar_color is not None: palette.setColor(QtGui.QPalette.Highlight, bar_color) # Ensure the colour of the text on the filled in bit of the progress # bar has good contrast: if highlight_text_color is not None: palette.setColor(QtGui.QPalette.HighlightedText, highlight_text_color) if regular_text_color is not None: palette.setColor(QtGui.QPalette.Text, regular_text_color) self.bar.setPalette(palette) else: self.bar_text_prefix = None # Default palette: self.bar.setPalette(self.style.standardPalette())
def status_monitor(self): # When called with a queue, this function writes to the queue # when the pulseblaster is waiting. This indicates the end of # an experimental run. self.status = yield (self.queue_work(self._primary_worker, 'check_status')) for key in self.status_bits: if self.status[key]: icon = QtGui.QIcon(':/qtutils/fugue/tick') else: icon = QtGui.QIcon(':/qtutils/fugue/cross') pixmap = icon.pixmap(QtCore.QSize(16, 16)) self.bit_values_widgets[key].setPixmap(pixmap)
def setWidget(self, logical_index, widget=None): header_item = self.model.horizontalHeaderItem(logical_index) if header_item is None: self.model.setHorizontalHeaderItem(logical_index, QtGui.QStandardItem()) if widget is None: if logical_index in self.widgets: widget = self.widgets[logical_index] widget.setParent(None) del self.widgets[logical_index] widget.removeEventFilter(self) del self.indents[widget] label_text = self.model.headerData(logical_index, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole) # Compatibility with both API types: if isinstance(label_text, QtCore.QVariant): if label_text.isNull(): return else: label_text = label_text.toString() if label_text is None: return else: raw_label_text = label_text.replace(self.thinspace, '') self.model.setHeaderData(logical_index, QtCore.Qt.Horizontal, raw_label_text, QtCore.Qt.DisplayRole) else: self.widgets[logical_index] = widget widget.setParent(self) widget.installEventFilter(self) if not self.isSectionHidden(logical_index) and not widget.isVisible(): widget.show() self.update_indents() self.update_widget_positions()
def __init__(self, *args, **kwargs): Plot.__init__(self, *args, **kwargs) self.points_of_interest_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/target--plus'), 'Add points of interest', self.on_add_points_of_interest_triggered) self.points_of_interest_action.setToolTip('Add points of interest') self.points_of_interest_action.setCheckable(True) self.actions_enabled = True self.canvas.mpl_connect('button_press_event', self.canvasClicked) self.remove_points_of_interest_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/target--minus'), 'Remove points of interest', self.on_remove_points_of_interest_triggered) self.remove_points_of_interest_action.setToolTip( 'Remove points of interest') self.remove_points_of_interest_action.setCheckable(True) self.canvas.mpl_connect('pick_event', self.onPick) self.clear_points_of_interest_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/target--exclamation'), 'Clear all points of interest', self.on_clear_points_of_interest_triggered) self.clear_points_of_interest_action.setToolTip( 'Cear all points of interest') self.done_action = self.navigation_toolbar.addAction( QtWidgets.QIcon(':qtutils/fugue/disk--arrow'), 'Done', self.save_points_of_interest) self.done_action.setToolTip('Save vortex locations') self.reject_action = self.navigation_toolbar.addAction( QtWidgets.QIcon(':qtutils/fugue/disk--minus'), 'Reject', self.on_reject) self.reject_action.setToolTip('Reject shot') self.cancel_action = self.navigation_toolbar.addAction( QtWidgets.QIcon(':qtutils/fugue/disk--exclamation'), 'Cancel', self.on_reject) self.cancel_action.setToolTip( 'Cancel (do not save any results for this shot)')
def __init__(self, figure, identifier, filepath): self.identifier = identifier loader = UiLoader() self.ui = loader.load(os.path.join(LYSE_DIR, 'plot_window.ui'), PlotWindow()) # Tell Windows how to handle our windows in the the taskbar, making pinning work properly and stuff: if os.name == 'nt': self.ui.newWindow.connect(set_win_appusermodel) self.set_window_title(identifier, filepath) # figure.tight_layout() self.figure = figure self.canvas = figure.canvas self.navigation_toolbar = NavigationToolbar(self.canvas, self.ui) self.lock_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/lock-unlock'), 'Lock axes', self.on_lock_axes_triggered) self.lock_action.setCheckable(True) self.lock_action.setToolTip('Lock axes') self.copy_to_clipboard_action = self.navigation_toolbar.addAction( QtGui.QIcon(':qtutils/fugue/clipboard--arrow'), 'Copy to clipboard', self.on_copy_to_clipboard_triggered) self.copy_to_clipboard_action.setToolTip('Copy to clipboard') self.copy_to_clipboard_action.setShortcut(QtGui.QKeySequence.Copy) self.ui.verticalLayout_canvas.addWidget(self.canvas) self.ui.verticalLayout_navigation_toolbar.addWidget( self.navigation_toolbar) self.lock_axes = False self.axis_limits = None self.update_window_size() self.ui.show()
def __init__(self, imagepath): self.qapplication = QtWidgets.QApplication.instance() if self.qapplication is None: self.qapplication = QtWidgets.QApplication(sys.argv) QtWidgets.QFrame.__init__(self) self.icon = QtGui.QPixmap() self.icon.load(imagepath) if self.icon.isNull(): raise ValueError("Invalid image file: {}.\n".format(imagepath)) self.icon = self.icon.scaled(self.imwidth, self.imheight, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.text = 'Loading' self.setWindowFlags(Qt.SplashScreen) self.setWindowOpacity(self.alpha) self.label = QtWidgets.QLabel(self.text) self.setStyleSheet("background-color: %s; font-size: 10pt" % self.BG) # Frame not necessary on macos, and looks ugly. if sys.platform != 'darwin': self.setFrameShape(QtWidgets.QFrame.StyledPanel) self.label.setWordWrap(True) self.label.setAlignment(Qt.AlignCenter) self.resize(self.w, self.h) image_label = QtWidgets.QLabel() image_label.setPixmap(self.icon) image_label.setAlignment(Qt.AlignCenter) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(image_label) layout.addWidget(self.label) center_point = QtWidgets.QDesktopWidget().availableGeometry().center() x0, y0 = center_point.x(), center_point.y() self.move(x0 - self.w / 2, y0 - self.h / 2) self._first_paint_complete = False
def __init__(self): self.window = QtGui.QWidget() self.window.resize(640, 480) layout = QtGui.QVBoxLayout(self.window) self.model = QtGui.QStandardItemModel() self.treeview = QtGui.QTreeView(self.window) self.header = HorizontalHeaderViewWithWidgets(self.model) self.treeview.setSortingEnabled(True) self.model.setHorizontalHeaderLabels(['Delete', 'Name', 'Value', 'Units', 'Expansion']) self.button = QtGui.QPushButton('hello, world!') self.button.setIcon(QtGui.QIcon(':qtutils/fugue/smiley-lol')) self.button2 = QtGui.QToolButton() self.button2.setIcon(QtGui.QIcon(':qtutils/fugue/plus')) self.button3 = QtGui.QToolButton() self.button3.setMinimumHeight(50) self.button3.setIcon(QtGui.QIcon(':qtutils/fugue/minus')) self.button4 = QtGui.QCheckBox() self.header.setWidget(0, self.button) self.header.setWidget(1, self.button2) self.header.setWidget(2, self.button3) self.header.setWidget(4, self.button4) self.treeview.setHeader(self.header) self.treeview.setModel(self.model) layout.addWidget(self.treeview) self.model.insertColumn(2, [QtGui.QStandardItem('test')]) self.window.show() for col in range(self.model.columnCount()): self.treeview.resizeColumnToContents(col) QtCore.QTimer.singleShot(2000, lambda: self.header.hideSection(3)) QtCore.QTimer.singleShot(4000, lambda: self.header.showSection(3)) QtCore.QTimer.singleShot(6000, lambda: self.header.setWidget(0, None)) QtCore.QTimer.singleShot(8000, lambda: self.header.setWidget(0, self.button))
self.button2.setIcon(QtGui.QIcon(':qtutils/fugue/plus')) self.button3 = QtGui.QToolButton() self.button3.setMinimumHeight(50) self.button3.setIcon(QtGui.QIcon(':qtutils/fugue/minus')) self.button4 = QtGui.QCheckBox() self.header.setWidget(0, self.button) self.header.setWidget(1, self.button2) self.header.setWidget(2, self.button3) self.header.setWidget(4, self.button4) self.treeview.setHeader(self.header) self.treeview.setModel(self.model) layout.addWidget(self.treeview) self.model.insertColumn(2, [QtGui.QStandardItem('test')]) self.window.show() for col in range(self.model.columnCount()): self.treeview.resizeColumnToContents(col) QtCore.QTimer.singleShot(2000, lambda: self.header.hideSection(3)) QtCore.QTimer.singleShot(4000, lambda: self.header.showSection(3)) QtCore.QTimer.singleShot(6000, lambda: self.header.setWidget(0, None)) QtCore.QTimer.singleShot(8000, lambda: self.header.setWidget(0, self.button)) qapplication = QtGui.QApplication(sys.argv) qapplication.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus, False) app = TestApp() qapplication.exec_()
def initialise_GUI(self): do_prop = {} for i in range( self.num_DO ): # 12 is the maximum number of flags on this device (some only have 4 though) do_prop['flag %d' % i] = {} # Create the output objects self.create_digital_outputs(do_prop) # Create widgets for output objects dds_widgets, ao_widgets, do_widgets = self.auto_create_widgets() # Define the sort function for the digital outputs def sort(channel): flag = channel.replace('flag ', '') flag = int(flag) return '%02d' % (flag) # and auto place the widgets in the UI self.auto_place_widgets(("Flags", do_widgets, sort)) # Store the board number to be used connection_object = self.settings['connection_table'].find_by_name( self.device_name) self.board_number = int(connection_object.BLACS_connection) # And which scheme we're using for buffered output programming and triggering: # (default values for backward compat with old connection tables) self.programming_scheme = connection_object.properties.get( 'programming_scheme', 'pb_start/BRANCH') # Create and set the primary worker self.create_worker( "main_worker", self.device_worker_class, { 'board_number': self.board_number, 'num_DO': self.num_DO, 'programming_scheme': self.programming_scheme }) self.primary_worker = "main_worker" # Set the capabilities of this device self.supports_smart_programming(True) #### adding status widgets from PulseBlaster.py # Load status monitor (and start/stop/reset buttons) UI ui = UiLoader().load( os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pulseblaster.ui')) self.get_tab_layout().addWidget(ui) # Connect signals for buttons ui.start_button.clicked.connect(self.start) ui.stop_button.clicked.connect(self.stop) ui.reset_button.clicked.connect(self.reset) # Add icons ui.start_button.setIcon(QtGui.QIcon(':/qtutils/fugue/control')) ui.start_button.setToolTip('Start') ui.stop_button.setIcon( QtGui.QIcon(':/qtutils/fugue/control-stop-square')) ui.stop_button.setToolTip('Stop') ui.reset_button.setIcon(QtGui.QIcon(':/qtutils/fugue/arrow-circle')) ui.reset_button.setToolTip('Reset') # initialise dictionaries of data to display and get references to the QLabels self.status_states = ['stopped', 'reset', 'running', 'waiting'] self.status = {} self.status_widgets = {} for state in self.status_states: self.status[state] = False self.status_widgets[state] = getattr(ui, '%s_label' % state) # Status monitor timout self.statemachine_timeout_add(2000, self.status_monitor)