def test_save_image(): file = NamedTemporaryFile() # no file extension is specified so cannot determine the image format with pytest.raises(OSError, match=r'Cannot save image'): utils.save_image(QtWidgets.QWidget(), file.name) path = file.name + '.png' assert not os.path.isfile(path) pixmap = utils.save_image(QtWidgets.QWidget(), path) assert os.path.isfile(path) assert isinstance(pixmap, QtGui.QPixmap) file.close()
def add_qt_tab(self, label, icons): """Add the Qt icons.""" tab = QtWidgets.QWidget() self.tab_widget.addTab(tab, label) layout = QtWidgets.QGridLayout() self.update_message('Loading Qt icons...') count = 0 num_cols = 4 for i in icons: button = QtWidgets.QPushButton(i) ico = convert.to_qicon(getattr(QtWidgets.QStyle, i)) button.setIcon(ico) button.clicked.connect(lambda *args, ic=ico, n=i: self.zoom(ic, n)) layout.addWidget(button, count // num_cols, count % num_cols) count += 1 self.num_icons += 1 tab.setLayout(layout) self.file_index += 1 self.progress_bar.setValue(self.file_index)
def show(): app = application() window = QtWidgets.QWidget() window.setWindowTitle('Toggle Switch Example') hbox = QtWidgets.QHBoxLayout() ts = ToggleSwitch(window) ts.toggled.connect(print_state) hbox.addWidget(ts) window.setLayout(hbox) window.show() app.exec_()
def read_n_raw_readings(self, n_meas=250, trig_interval=0.02): """ Parameters ---------- n_meas : int number of measurements to collect Returns ------- tuple of t0_s, data. t0_s is the initial time in number of seconds passed since epoch; data is a list of n_meas raw values from the RF counter, in Hz """ # set up for fast graphing app = application() mw = QtWidgets.QMainWindow() mw.setWindowTitle("Capacitor raw data") cw = QtWidgets.QWidget() mw.setCentralWidget(cw) layout = QtWidgets.QVBoxLayout() cw.setLayout(layout) pw1 = pg.PlotWidget(name='Capacitor raw data') curve = pw1.plot() layout.addWidget(pw1) mw.show() self.rfcounter.write("INPUT:LEVEL:AUTO ONCE") # only need to get frequency level once self.rfcounter.write("INIT") # starts waiting for a trigger data = np.empty(n_meas) if self.triggerer is not None: self.triggerer.start_trigger() t0_s = time_ns()/1e9 rdgs_per_s = 1/trig_interval for i in range(n_meas): a = self.rfcounter.query("DATA:REM? 1,WAIT") # a is a string # read one data value taken from memory to buffer; remove value from memory after reading data[i] = float(a.strip("\n")) if i % rdgs_per_s == 0: # update plot every second curve.setData(data[:i]) # show only the collected data app.processEvents() if self.triggerer is not None: self.triggerer.stop_trigger() t1_s = time_ns() / 1e9 print("Elapsed time: {}".format(t1_s - t0_s)) return t0_s, data
def add_windows_tab(self): """Add the icons from the Windows DLL and EXE files.""" num_cols = 16 filename = self.windows_files[self.windows_index] self.update_message('Loading icons from {}...'.format(filename)) tab = QtWidgets.QWidget() self.tab_widget.addTab(tab, filename) layout = QtWidgets.QGridLayout() index = 0 while True: button = QtWidgets.QPushButton(str(index)) try: name = '{}|{}'.format(filename, str(index)) ico = convert.to_qicon(name) except OSError: break button.setIcon(ico) button.clicked.connect( lambda *args, ic=ico, n=name: self.zoom(ic, n)) layout.addWidget(button, index // num_cols, index % num_cols) index += 1 self.num_icons += 1 self.file_index += 1 self.progress_bar.setValue(self.file_index) tab.setLayout(layout) self.windows_index += 1 if self.windows_index == len(self.windows_files): self.timer.stop() self.update_message('Loaded {} icons.'.format(self.num_icons)) self.progress_bar.hide()
def __init__(self, connection, parent=None): """ A :class:`~QtWidgets.QWidget` for a :class:`~msl.equipment.connection_message_based.ConnectionMessageBased` connection. This widget allows for reading/writing messages from/to equipment. Parameters ---------- connection : :class:`~msl.equipment.connection_message_based.ConnectionMessageBased` The connection to the equipment. parent : :class:`QtWidgets.QWidget` The parent widget. Example ------- To view an example of the :class:`MessageBased` widget that will send messages to a *dummy* :class:`~msl.equipment.record_types.EquipmentRecord` in demo mode, run: >>> from msl.examples.qt.equipment import message_based # doctest: +SKIP >>> message_based.show() # doctest: +SKIP """ super(MessageBased, self).__init__(parent=parent) r = connection.equipment_record self.setWindowTitle('{} || {} || {}'.format(r.manufacturer, r.model, r.serial)) self.setAcceptDrops(True) self._conn = connection self._dropped_commands = [] self._abort_execution = False self._command_list = [] self._header = ['Action', 'Delay', 'Message', 'Reply'] self._actions = ['write', 'read', 'query', 'delay'] self._table = QtWidgets.QTableWidget(0, len(self._header), self) self._table.setHorizontalHeaderLabels(self._header) self._table.horizontalHeader().setStretchLastSection(True) self._table.horizontalHeader().setContextMenuPolicy( QtCore.Qt.CustomContextMenu) self._table.horizontalHeader().customContextMenuRequested.connect( self._show_horizontal_popup_menu) self._table.verticalHeader().setContextMenuPolicy( QtCore.Qt.CustomContextMenu) self._table.verticalHeader().customContextMenuRequested.connect( self._show_vertical_popup_menu) self._timeout_spinbox = QtWidgets.QDoubleSpinBox() self._timeout_spinbox.setToolTip( '<html>The timeout value to use for <i>read</i> commands</html>') self._timeout_spinbox.setRange(0, 999999999) if 'ConnectionPyVISA' in '{}'.format( connection.__class__.__bases__): # a PyVISA connection self._timeout_spinbox.setSuffix(' ms') self._timeout_spinbox.setDecimals(0) else: self._timeout_spinbox.setSuffix(' s') self._timeout_spinbox.setDecimals(2) try: self._timeout_spinbox.setValue(self._conn.timeout) except TypeError: # in case the connection is established in demo mode self._timeout_spinbox.setValue(0) self._timeout_spinbox.valueChanged.connect(self._update_timeout) self._use_rows = QtWidgets.QLineEdit() self._use_rows.setToolTip( 'Enter the rows to execute or leave blank to execute all rows.\nFor example: 1,3,5-8' ) self._execute_icon = get_icon(QtWidgets.QStyle.SP_ArrowRight) self._continuous_icon = get_icon(QtWidgets.QStyle.SP_BrowserReload) self._abort_icon = get_icon(QtWidgets.QStyle.SP_BrowserStop) self._clear_icon = get_icon(QtWidgets.QStyle.SP_DialogResetButton) self._remove_icon = get_icon(QtWidgets.QStyle.SP_DialogCancelButton) self._insert_before_icon = get_icon(QtWidgets.QStyle.SP_DialogOkButton) # create an insert_after_icon by transforming the insert_before_icon size = self._insert_before_icon.availableSizes()[-1] pixmap = self._insert_before_icon.pixmap(size).transformed( QtGui.QTransform().scale(-1, 1)) self._insert_after_icon = QtGui.QIcon(pixmap) self._execute_thread = _Execute(self) self._execute_thread.finished.connect(self._check_if_looping) self._execute_thread.sig_error.connect(self._execute_error) self._execute_thread.sig_update_row_color.connect( self._update_row_appearance) self._execute_thread.sig_highlight_row.connect(self._highlight_row) self._execute_thread.sig_update_reply.connect(self._update_reply) self._execute_thread.sig_show_execute_icon.connect( self._show_execute_icon) self._loop_checkbox = QtWidgets.QCheckBox() self._loop_checkbox.setToolTip('Run continuously?') self._loop_checkbox.clicked.connect(self._show_execute_icon) save_icon = get_icon(QtWidgets.QStyle.SP_DriveFDIcon) self._save_button = QtWidgets.QPushButton(save_icon, 'Save') self._save_button.setToolTip('Save the table to a tab-delimited file') self._save_button.clicked.connect(self._save) self._info_button = QtWidgets.QPushButton( get_icon(QtWidgets.QStyle.SP_FileDialogInfoView), '') self._info_button.setToolTip( 'Display the information about the equipment') self._info_button.clicked.connect( lambda clicked, record=r: show_record(record)) self._status_label = QtWidgets.QLabel() self._execute_button = QtWidgets.QPushButton() self._execute_button.clicked.connect(self._execute_start) self._show_execute_icon() self._status_label.setText('Create a new Execution Table or\n' 'Drag & Drop or Copy & Paste\n' 'a previous Execution Table') execute_widget = QtWidgets.QWidget() grid = QtWidgets.QGridLayout() grid.addWidget(QtWidgets.QLabel('Timeout'), 1, 0, alignment=QtCore.Qt.AlignRight) grid.addWidget(self._timeout_spinbox, 1, 1, 1, 2) grid.addWidget(QtWidgets.QLabel('Rows'), 2, 0, alignment=QtCore.Qt.AlignRight) grid.addWidget(self._use_rows, 2, 1, 1, 2) grid.addWidget(self._execute_button, 3, 0, 1, 2) grid.addWidget(self._loop_checkbox, 3, 2, 1, 1, alignment=QtCore.Qt.AlignLeft) grid.addWidget(self._save_button, 4, 0, 1, 2) grid.addWidget(self._info_button, 4, 2, 1, 1) grid.addWidget(self._status_label, 5, 0, 1, 3, alignment=QtCore.Qt.AlignBottom) grid.setRowStretch(5, 1) execute_widget.setLayout(grid) self._create_row() self._table.resizeColumnsToContents() splitter = QtWidgets.QSplitter() splitter.addWidget(self._table) splitter.addWidget(execute_widget) splitter.setStretchFactor(0, 1) splitter.setChildrenCollapsible(False) splitter.setSizes([1, 0]) hbox = QtWidgets.QHBoxLayout() hbox.addWidget(splitter) self.setLayout(hbox)
import os from datetime import datetime from time import time, time_ns, sleep import numpy as np import matplotlib.pyplot as plt import pyqtgraph as pg from msl.qt import QtWidgets, application from equip import CetoniSP from data_handling import fit_sinusoid app = application() mw = QtWidgets.QMainWindow() mw.setWindowTitle("Syringe pump fill level") cw = QtWidgets.QWidget() mw.setCentralWidget(cw) layout = QtWidgets.QVBoxLayout() cw.setLayout(layout) pw1 = pg.PlotWidget(name='Syringe pump fill level') curve = pw1.plot() layout.addWidget(pw1) class Experimenter(object): def __init__(self): self.sp = None self.t_data = [] # time in seconds self.fl_data = [] # syringe plunger fill level in unit set (mL)