Esempio n. 1
0
File: led.py Progetto: MSLNZ/msl-qt
 def sizeHint(self):
     """Overrides :meth:`QtWidgets.QWidget.sizeHint`."""
     if self._shape == Shapes.Triangle:
         return QtCore.QSize(self._triangle_factor*self._height_hint, self._height_hint)
     elif self._shape == Shapes.Rounded:
         return QtCore.QSize(self._rounded_factor*self._height_hint, self._height_hint)
     return QtCore.QSize(self._height_hint, self._height_hint)
Esempio n. 2
0
    def __init__(self):

        app = application()

        self.tab_widget = QtWidgets.QTabWidget()

        self.main_window = QtWidgets.QMainWindow()
        self.main_window.setWindowTitle('Standard Icons')
        self.main_window.setCentralWidget(self.tab_widget)
        self.main_window.closeEvent = self.close_event

        # add a progress bar to the status bar
        self.progress_bar = QtWidgets.QProgressBar(
            self.main_window.statusBar())
        self.progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.main_window.statusBar().addPermanentWidget(self.progress_bar)
        self.main_window.showMaximized()

        self.num_icons = 0
        self.file_index = 0
        self.zoom_widget = QtWidgets.QDialog()
        self.zoom_widget.setSizeGripEnabled(True)
        self.zoom_widget.resize(QtCore.QSize(256, 256))
        self.zoom_widget.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
        vbox = QtWidgets.QVBoxLayout()
        self.zoom_label = QtWidgets.QLabel()
        self.zoom_label.setScaledContents(True)
        vbox.addWidget(self.zoom_label)
        self.zoom_widget.setLayout(vbox)

        qt_icons = [sp for sp in dir(QtWidgets.QStyle) if sp.startswith('SP_')]

        self.windows_files = [
            'accessibilitycpl', 'compstui', 'ddores', 'dmdskres', 'explorer',
            'gameux', 'ieframe', 'imageres', 'mmcndmgr', 'mmres', 'moricons',
            'netcenter', 'netshell', 'networkexplorer', 'pifmgr', 'pnidui',
            'sensorscpl', 'setupapi', 'shell32', 'wmploc', 'wpdshext'
        ]

        self.num_files = 1 + len(self.windows_files)
        self.progress_bar.setRange(0, self.num_files)

        self.add_qt_tab('Qt Icons', qt_icons)

        if has_clr:
            self.windows_index = 0
            self.timer = QtCore.QTimer()
            self.timer.timeout.connect(self.add_windows_tab)
            self.timer.start(0)
        else:
            self.update_message('Loaded {} icons.'.format(self.num_icons))
            self.progress_bar.hide()

        app.exec()
Esempio n. 3
0
def test_icon_size():
    int_val = QtWidgets.QStyle.SP_DriveNetIcon
    icon = convert.to_qicon(int_val)
    sizes = icon.availableSizes()
    if sys.platform == 'win32':
        assert len(sizes) > 1

    #
    # specify the size to the get_icon function
    #

    b = Button(icon=convert.to_qicon(int_val))
    assert b.text() == ''
    assert b.toolButtonStyle() == Qt.ToolButtonIconOnly
    assert b.iconSize() == sizes[0]

    b = Button(icon=convert.to_qicon(int_val, size=789))
    assert b.iconSize() == QtCore.QSize(789, 789)

    b = Button(icon=convert.to_qicon(int_val, size=3.0))
    # specifying a scale factor will use the largest available size
    assert b.iconSize() == QtCore.QSize(3 * sizes[-1].width(),
                                        3 * sizes[-1].height())

    b = Button(icon=convert.to_qicon(int_val, size=QtCore.QSize(50, 50)))
    assert b.iconSize() == QtCore.QSize(50, 50)

    for size in [(256, ), (256, 256, 256)]:
        with pytest.raises(ValueError, match='(width, height)'):
            Button(icon=convert.to_qicon(int_val, size=size))

    #
    # use the icon_size kwarg
    #

    b = Button(icon=convert.to_qicon(int_val), icon_size=1234)
    assert b.iconSize() == QtCore.QSize(1234, 1234)

    b = Button(icon=convert.to_qicon(int_val), icon_size=3.0)
    # specifying a scale factor will use the largest available size
    assert b.iconSize() == QtCore.QSize(3 * sizes[-1].width(),
                                        3 * sizes[-1].height())

    b = Button(icon=convert.to_qicon(int_val), icon_size=(312, 312))
    assert b.iconSize() == QtCore.QSize(312, 312)

    b = Button(icon=convert.to_qicon(int_val),
               icon_size=QtCore.QSize(500, 500))
    assert b.iconSize() == QtCore.QSize(500, 500)

    for size in [(256, ), (256, 256, 256)]:
        with pytest.raises(ValueError, match='(width, height)'):
            Button(icon=convert.to_qicon(int_val), icon_size=size)
Esempio n. 4
0
def test_icon():
    path = os.path.dirname(__file__) + '/gamma.png'
    gamma_size = QtCore.QSize(191, 291)

    int_val = QtWidgets.QStyle.SP_DriveNetIcon
    icon = convert.to_qicon(int_val)
    sizes = icon.availableSizes()
    if sys.platform == 'win32':
        assert len(sizes) > 1

    b = Button(icon=int_val)
    assert b.text() == ''
    assert not b.icon().isNull()
    assert b.iconSize() == sizes[0]
    assert b.toolButtonStyle() == Qt.ToolButtonIconOnly

    b = Button(icon=path)
    assert b.text() == ''
    assert not b.icon().isNull()
    assert b.iconSize() == gamma_size
    assert b.toolButtonStyle() == Qt.ToolButtonIconOnly

    b = Button(icon=convert.icon_to_base64(convert.to_qicon(path)))
    assert b.text() == ''
    assert not b.icon().isNull()
    assert b.iconSize() == gamma_size
    assert b.toolButtonStyle() == Qt.ToolButtonIconOnly
Esempio n. 5
0
class _Execute(QtCore.QThread):

    sig_error = QtCore.pyqtSignal(str)
    sig_update_row_color = QtCore.pyqtSignal(str, int)
    sig_highlight_row = QtCore.pyqtSignal(int)
    sig_update_reply = QtCore.pyqtSignal(int, str)
    sig_show_execute_icon = QtCore.pyqtSignal()

    def __init__(self, parent):
        QtCore.QThread.__init__(self)
        self.parent = parent
        self._error = False

    def run(self):
        if self._error:
            return

        for index, action, delay, message in self.parent._command_list:
            if self._error or self.parent._abort_execution:
                self.sig_show_execute_icon.emit()
                break

            self.sig_highlight_row.emit(index)
            try:
                if action == 'read':
                    if delay > 0:
                        time.sleep(delay)
                    reply = self.parent._conn.read()
                elif action == 'write':
                    num_bytes = self.parent._conn.write(message)
                    reply = '<sent {} bytes>'.format(num_bytes)
                elif action == 'query':
                    reply = self.parent._conn.query(message, delay)
                elif action == 'delay':
                    time.sleep(delay)
                    reply = ''
                else:
                    assert False, 'Method "{}" not implemented'.format(action)
                self.sig_update_reply.emit(index, reply.strip())
            except Exception:
                self._error = True
                self.sig_error.emit('Row {}: {}({})\n\n{}'.format(
                    index + 1, action, message, traceback.format_exc()))
                break
            finally:
                self.sig_update_row_color.emit(action, index)
Esempio n. 6
0
File: led.py Progetto: MSLNZ/msl-qt
    def paintEvent(self, event):
        """Overrides :meth:`QtWidgets.QWidget.paintEvent`."""
        option = QtWidgets.QStyleOption()
        option.initFrom(self)

        h = option.rect.height()
        w = option.rect.width()
        if self._shape == Shapes.Triangle or self._shape == Shapes.Rounded:
            aspect = self._triangle_factor if self._shape == Shapes.Triangle else self._rounded_factor
            ah = w / aspect
            aw = w
            if ah > h:
                ah = h
                aw = h * aspect
            x = abs(aw - w) / 2.0
            y = abs(ah - h) / 2.0
            bounds = QtCore.QRectF(x, y, aw, ah)
        else:
            size = min(w, h)
            x = abs(size - w) / 2.0
            y = abs(size - h) / 2.0
            bounds = QtCore.QRectF(x, y, size, size)

        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)

        if self.isEnabled():
            color = self._on_color if self._is_on else self._off_color
        else:
            color = QtGui.QColor('#BDBDBD')

        lighter = QtGui.QColor(color).lighter(150)  # 150 -> 50% brighter

        color_str = 'rgb(%d,%d,%d)' % (color.red(), color.green(), color.blue())
        lighter_str = 'rgb(%d,%d,%d)' % (lighter.red(), lighter.green(), lighter.blue())

        svg = (SVG_MAP[self._shape] % (color_str, lighter_str)).encode('utf8')
        self._renderer.load(QtCore.QByteArray(svg))
        self._renderer.render(painter, bounds)
Esempio n. 7
0
def test_to_qicon():

    assert isinstance(convert.to_qicon(QtGui.QIcon()), QtGui.QIcon)
    assert isinstance(convert.to_qicon(QtGui.QPixmap()), QtGui.QIcon)
    assert isinstance(convert.to_qicon(QtGui.QImage()), QtGui.QIcon)
    assert isinstance(convert.to_qicon(QtWidgets.QStyle.SP_TitleBarMenuButton),
                      QtGui.QIcon)
    assert isinstance(convert.to_qicon(14), QtGui.QIcon)

    base64 = 'iVBORw0KGgoAAAANSUhEUgAAACgAAABCCAYAAAAlkZRRAAAACXBIWXMAAAsTAAALEwEAmpwYAAABpElEQVR' \
             'oge2ZT07CQBSHf29kLXKOsnApBEx7DAl3sT2BZzAx6C1ahYBLFzRxyQ1Q12SeiwoSQonjzMiLmW9Fh+nMlz' \
             'ft/HkFhEOuGnofRLz+3RyVztpVrhryhXjBhu8OlsN2DADQ/NYalS+m93sXVJpzACBGASAxvt+1kGuCoC3On' \
             'kGXc9824iMYBG0JgrZ4X0lMWe+KtKKkdTcvQgT3sRy2Y6URr6+bo3laV/cogpUcX28VpbV1vdtY4iyCYcsv' \
             'lSBoi7j94G474iMoXjDMg7YEQVvEC4rPDxq/xctBdH7CuAGA0/vSOBlkivk0o+iMNcfuVWq6+6uOfot4wdo' \
             'h/riKcqbqYOMrMfQTxEdQvKC4/eAu4iMYBG0RL9gAthd6yg4lco6B+AiKFzSfB1erBVQj8+CyF2PB1sPrAg' \
             'fyea4RP8TiBb+GmDIA0ArF5h/CLUCPx5AKuISAsJJYIV4w8O8hAOj2O9VbTJRNn6YpAHT6nZxQnYun49nmQ' \
             'NTrXcSaKN8t37RRU85AMRvPEgDoXnZT8Pe3un31FXMymTzL/xwrXlA8n2MHdwPYAbB5AAAAAElFTkSuQmCC'

    assert isinstance(convert.to_qicon(QtCore.QByteArray(base64.encode())),
                      QtGui.QIcon)
    assert isinstance(convert.to_qicon(bytearray(base64.encode())),
                      QtGui.QIcon)

    default_size = convert.to_qicon(
        QtWidgets.QStyle.SP_TitleBarMenuButton).availableSizes()[-1]
    assert isinstance(default_size, QtCore.QSize)

    with pytest.raises(TypeError):
        convert.to_qicon(None)

    with pytest.raises(OSError):
        convert.to_qicon(99999)  # not a valid QStyle.StandardPixmap enum value

    with pytest.raises(OSError):
        convert.to_qicon('this is not an icon')

    assert isinstance(
        convert.to_qicon(os.path.join(os.path.dirname(__file__), 'gamma.png')),
        QtGui.QIcon)

    # insert this directory into sys.path and check again
    sys.path.insert(0, os.path.dirname(__file__))
    assert isinstance(convert.to_qicon('gamma.png'), QtGui.QIcon)

    icon_1 = convert.to_qicon('gamma.png').availableSizes()[0]
    icon_2 = convert.to_qicon('gamma.png', size=0.5).availableSizes()[0]
    assert int(icon_1.width() * 0.5) == icon_2.width()
    assert int(icon_1.height() * 0.5) == icon_2.height()
Esempio n. 8
0
def test_drag_enter_paths():
    mime = QtCore.QMimeData()

    event = QtGui.QDragEnterEvent(QtCore.QPoint(0, 0), Qt.CopyAction, mime,
                                  Qt.LeftButton, Qt.NoModifier)
    paths = utils.drag_drop_paths(event)
    assert len(paths) == 0

    url1 = QtCore.QUrl('/path/to/image.jpeg')
    url1.setScheme('file')

    url2 = QtCore.QUrl(
        '')  # does not pass the isValid() and scheme() == 'file' checks

    url3 = QtCore.QUrl('/path/to/image.jpeg')
    url3.setScheme('ftp')  # does not pass the scheme() == 'file' check

    url4 = QtCore.QUrl('/path/to/image.png')
    url4.setScheme('file')

    url5 = QtCore.QUrl('/path/to/image2.jpg')
    url5.setScheme('file')

    mime.setUrls([url1, url2, url3, url4, url5])
    event = QtGui.QDragEnterEvent(QtCore.QPoint(0, 0), Qt.CopyAction, mime,
                                  Qt.LeftButton, Qt.NoModifier)

    paths = utils.drag_drop_paths(event)
    assert len(paths) == 3
    assert '/path/to/image.jpeg' in paths
    assert '/path/to/image.png' in paths
    assert '/path/to/image2.jpg' in paths

    paths = utils.drag_drop_paths(event, pattern='*.jp*g')
    assert len(paths) == 2
    assert '/path/to/image.jpeg' in paths
    assert '/path/to/image2.jpg' in paths

    paths = utils.drag_drop_paths(event, pattern='*.png')
    assert len(paths) == 1
    assert '/path/to/image.png' in paths
Esempio n. 9
0
    def __init__(self, parent=None):
        super(BlinkingLEDs, self).__init__(parent)

        self.setWindowTitle('Blinking LEDs')

        # The shape can be an enum value or member name (case in-sensitive)
        # The color can be anything that msl.qt.utils.to_qcolor() accepts
        params = [
            {
                'shape': LED.Circle,
                'on_color': Qt.darkGreen,
                'clickable': True
            },
            {
                'shape': 'rouNDed',
                'on_color': (78, 82, 107)
            },
            {
                'shape': 2,
                'on_color': 'cyan',
                'clickable': True
            },
            {
                'shape': 'Triangle',
                'on_color': '#6b3064'
            },
        ]

        self.leds = []
        layout = QtWidgets.QHBoxLayout()
        for kwargs in params:
            led = LED(**kwargs)
            led.toggled.connect(self.led_state_changed)
            led.clicked.connect(self.led_was_clicked)
            layout.addWidget(led)
            self.leds.append(led)
        self.setLayout(layout)

        self._timer = QtCore.QTimer()
        self._timer.timeout.connect(self.toggle_random_led)
        self._timer.start(200)
Esempio n. 10
0
    def select_zoom(self, event):
        """Called when the user wants to zoom in."""
        event.accept()
        if self.canvas.image is None:
            return

        if event.button() & (QtCore.Qt.LeftButton | QtCore.Qt.MidButton):
            if event.isFinish():
                self.view_box.rbScaleBox.hide()

                # get the coordinates of the highlighted region
                rect = QtCore.QRectF(pg.Point(event.buttonDownPos(event.button())), pg.Point(event.pos()))
                rect = self.view_box.childGroup.mapRectFromParent(rect).normalized()

                # get the size of the image on the canvas
                # DO NOT use self.canvas.width(), self.canvas.height()
                height, width = self.original_image.shape[:2]
                if self.zoom_history:
                    width = int(self.zoom_history[-1][2] * width)
                    height = int(self.zoom_history[-1][3] * height)

                angle = self.rotate_slider.value()
                values = rotate_zoom(angle, rect, width, height)
                if values is None:
                    return  # zoom outside of the image

                x, y, w, h, width, height = values

                # convert to the coordinates of the original (un-zoomed) image
                if self.zoom_history:
                    orig_height, orig_width = self.original_image.shape[:2]
                    x2, y2, w2, h2 = self.zoom_history[-1]
                    x = x * width / orig_width + x2
                    y = y * height / orig_height + y2
                    w *= w2
                    h *= h2

                self.append_zoom(x, y, w, h)

            else:
                self.view_box.updateScaleBox(event.buttonDownPos(), event.pos())
Esempio n. 11
0
def test_icon_to_base64():
    # reading from a standard Qt icon does not raise any errors
    assert isinstance(
        convert.icon_to_base64(QtWidgets.QStyle.SP_TitleBarMenuButton),
        QtCore.QByteArray)

    # reading from a file does not raise any errors
    icon = convert.to_qicon('gamma.png')
    assert isinstance(convert.icon_to_base64(icon), QtCore.QByteArray)
    assert convert.icon_to_base64(icon).startsWith(b'iVBORw0KGgoAAAA')
    assert convert.icon_to_base64(icon,
                                  fmt='PNG').startsWith(b'iVBORw0KGgoAAAA')
    assert convert.icon_to_base64(icon,
                                  fmt='BMP').startsWith(b'Qk32jgIAAAAAADY')
    assert convert.icon_to_base64(icon,
                                  fmt='JPG').startsWith(b'/9j/4AAQSkZJRgA')
    assert convert.icon_to_base64(icon,
                                  fmt='JPEG').startsWith(b'/9j/4AAQSkZJRgA')

    # GIF is not supported
    with pytest.raises(ValueError):
        convert.icon_to_base64(icon, fmt='GIF')

    # the size of 'gamma.png'
    size = QtCore.QSize(191, 291)

    # convert back to a QIcon and check each pixel
    original = icon.pixmap(size).toImage()
    converted = convert.to_qicon(
        convert.icon_to_base64(icon)).pixmap(size).toImage()
    for x in range(0, size.width()):
        for y in range(0, size.height()):
            rgb_original = original.pixel(x, y)
            rgb_converted = converted.pixel(x, y)
            assert QtGui.QColor(rgb_original).getRgb() == QtGui.QColor(
                rgb_converted).getRgb()
Esempio n. 12
0
class _Settings(QtWidgets.QDialog):

    sig_update_jog_tooltip = QtCore.pyqtSignal()

    def __init__(self, parent):
        """Display a QDialog to edit the settings"""
        super(_Settings, self).__init__(flags=QtCore.Qt.WindowCloseButtonHint)

        self.conn = parent._connection

        info = self.conn.get_hardware_info()
        self.setWindowTitle(
            info.modelNumber.decode('utf-8') + ' || ' +
            info.notes.decode('utf-8'))

        # move info
        max_vel, max_acc = self.conn.get_motor_velocity_limits()
        vel, acc = self.conn.get_vel_params()
        vel = self.conn.get_real_value_from_device_unit(vel, UnitType.VELOCITY)
        acc = self.conn.get_real_value_from_device_unit(
            acc, UnitType.ACCELERATION)
        backlash = self.conn.get_real_value_from_device_unit(
            self.conn.get_backlash(), UnitType.DISTANCE)

        # move widgets
        self.acc_spinbox = QtWidgets.QDoubleSpinBox()
        self.acc_spinbox.setMinimum(0)
        self.acc_spinbox.setMaximum(max_acc)
        self.acc_spinbox.setValue(acc)
        self.acc_spinbox.setToolTip(
            '<html><b>Range:</b><br>0 - {} mm/s<sup>2</sup></html>'.format(
                max_acc))

        self.vel_spinbox = QtWidgets.QDoubleSpinBox()
        self.vel_spinbox.setMinimum(0)
        self.vel_spinbox.setMaximum(max_vel)
        self.vel_spinbox.setValue(vel)
        self.vel_spinbox.setToolTip(
            '<html><b>Range:</b><br>0 - {} mm/s</html>'.format(max_vel))

        self.backlash_spinbox = QtWidgets.QDoubleSpinBox()
        self.backlash_spinbox.setMinimum(0)
        self.backlash_spinbox.setMaximum(5)
        self.backlash_spinbox.setValue(backlash)
        self.backlash_spinbox.setToolTip(
            '<html><b>Range:</b><br>0 - 5 mm</html>')

        move_group = QtWidgets.QGroupBox('Move Parameters')
        move_grid = QtWidgets.QGridLayout()
        move_grid.addWidget(QtWidgets.QLabel('Backlash'),
                            0,
                            0,
                            alignment=QtCore.Qt.AlignRight)
        move_grid.addWidget(self.backlash_spinbox, 0, 1)
        move_grid.addWidget(QtWidgets.QLabel('mm'),
                            0,
                            2,
                            alignment=QtCore.Qt.AlignLeft)
        move_grid.addWidget(QtWidgets.QLabel('Maximum Velocity'),
                            1,
                            0,
                            alignment=QtCore.Qt.AlignRight)
        move_grid.addWidget(self.vel_spinbox, 1, 1)
        move_grid.addWidget(QtWidgets.QLabel('mm/s'),
                            1,
                            2,
                            alignment=QtCore.Qt.AlignLeft)
        move_grid.addWidget(QtWidgets.QLabel('Acceleration'),
                            2,
                            0,
                            alignment=QtCore.Qt.AlignRight)
        move_grid.addWidget(self.acc_spinbox, 2, 1)
        move_grid.addWidget(QtWidgets.QLabel('mm/s<sup>2</sup>'),
                            2,
                            2,
                            alignment=QtCore.Qt.AlignLeft)
        move_group.setLayout(move_grid)

        # jog info
        jog_size = self.conn.get_real_value_from_device_unit(
            self.conn.get_jog_step_size(), UnitType.DISTANCE)
        vel, acc = self.conn.get_jog_vel_params()
        jog_vel = self.conn.get_real_value_from_device_unit(
            vel, UnitType.VELOCITY)
        jog_acc = self.conn.get_real_value_from_device_unit(
            acc, UnitType.ACCELERATION)

        # jog widgets
        min_jog, max_jog = 0.002, parent._max_pos_mm / 2.0
        self.jog_size_spinbox = QtWidgets.QDoubleSpinBox()
        self.jog_size_spinbox.setMinimum(min_jog)
        self.jog_size_spinbox.setMaximum(max_jog)
        self.jog_size_spinbox.setDecimals(3)
        self.jog_size_spinbox.setValue(jog_size)
        self.jog_size_spinbox.setToolTip(
            '<html><b>Range:</b><br>{} - {} mm</html>'.format(
                min_jog, max_jog))

        self.jog_acc_spinbox = QtWidgets.QDoubleSpinBox()
        self.jog_acc_spinbox.setMinimum(0)
        self.jog_acc_spinbox.setMaximum(max_acc)
        self.jog_acc_spinbox.setValue(jog_acc)
        self.jog_acc_spinbox.setToolTip(
            '<html><b>Range:</b><br>0 - {} mm/s<sup>2</sup></html>'.format(
                max_acc))

        self.jog_vel_spinbox = QtWidgets.QDoubleSpinBox()
        self.jog_vel_spinbox.setMinimum(0)
        self.jog_vel_spinbox.setMaximum(max_vel)
        self.jog_vel_spinbox.setValue(jog_vel)
        self.jog_vel_spinbox.setToolTip(
            '<html><b>Range:</b><br>0 - {} mm/s</html>'.format(max_vel))

        jog_group = QtWidgets.QGroupBox('Jog Parameters')
        jog_grid = QtWidgets.QGridLayout()
        jog_grid.addWidget(QtWidgets.QLabel('Step Size'),
                           0,
                           0,
                           alignment=QtCore.Qt.AlignRight)
        jog_grid.addWidget(self.jog_size_spinbox, 0, 1)
        jog_grid.addWidget(QtWidgets.QLabel('mm'),
                           0,
                           2,
                           alignment=QtCore.Qt.AlignLeft)
        jog_grid.addWidget(QtWidgets.QLabel('Maximum Velocity'),
                           1,
                           0,
                           alignment=QtCore.Qt.AlignRight)
        jog_grid.addWidget(self.jog_vel_spinbox, 1, 1)
        jog_grid.addWidget(QtWidgets.QLabel('mm/s'),
                           1,
                           2,
                           alignment=QtCore.Qt.AlignLeft)
        jog_grid.addWidget(QtWidgets.QLabel('Acceleration'),
                           2,
                           0,
                           alignment=QtCore.Qt.AlignRight)
        jog_grid.addWidget(self.jog_acc_spinbox, 2, 1)
        jog_grid.addWidget(QtWidgets.QLabel('mm/s<sup>2</sup>'),
                           2,
                           2,
                           alignment=QtCore.Qt.AlignLeft)
        jog_group.setLayout(jog_grid)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addWidget(move_group)
        hbox.addWidget(jog_group)

        update_button = QtWidgets.QPushButton('Update')
        update_button.setToolTip('Update the device settings')
        update_button.clicked.connect(self.update_settings)

        cancel_button = QtWidgets.QPushButton('Cancel')
        cancel_button.setToolTip('Update the device settings')
        cancel_button.clicked.connect(self.close)

        info_button = QtWidgets.QPushButton()
        info_button.setIcon(get_icon('imageres|109'))
        info_button.clicked.connect(
            lambda: show_hardware_info(parent._connection))
        info_button.setToolTip('Display the hardware information')

        button_layout = QtWidgets.QGridLayout()
        button_layout.addWidget(cancel_button, 0, 0)
        button_layout.addItem(
            QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Expanding,
                                  QtWidgets.QSizePolicy.Expanding), 0, 1)
        button_layout.addWidget(update_button, 0, 2)
        button_layout.addWidget(info_button, 0, 3)

        vbox = QtWidgets.QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addLayout(button_layout)
        self.setLayout(vbox)

    def update_settings(self):
        vel = self.conn.get_device_unit_from_real_value(
            self.vel_spinbox.value(), UnitType.VELOCITY)
        acc = self.conn.get_device_unit_from_real_value(
            self.acc_spinbox.value(), UnitType.ACCELERATION)
        self.conn.set_vel_params(vel, acc)

        backlash = self.conn.get_device_unit_from_real_value(
            self.backlash_spinbox.value(), UnitType.DISTANCE)
        self.conn.set_backlash(backlash)

        jog_vel = self.conn.get_device_unit_from_real_value(
            self.jog_vel_spinbox.value(), UnitType.VELOCITY)
        jog_acc = self.conn.get_device_unit_from_real_value(
            self.jog_acc_spinbox.value(), UnitType.ACCELERATION)
        self.conn.set_jog_vel_params(jog_vel, jog_acc)

        jog_size = self.conn.get_device_unit_from_real_value(
            self.jog_size_spinbox.value(), UnitType.DISTANCE)
        self.conn.set_jog_step_size(jog_size)

        self.sig_update_jog_tooltip.emit()

        self.close()
Esempio n. 13
0
 class _Signaler(QtCore.QObject):
     """Used for sending a signal of the current position."""
     signal = QtCore.pyqtSignal()
Esempio n. 14
0
class _Tree(QtWidgets.QTreeWidget):

    sig_selected = QtCore.pyqtSignal(str)

    def __init__(self, equipment_table, connection_table):
        """A Tree view of the options to use as filters for the devices."""
        super(_Tree, self).__init__()

        # configure the super class
        self.setColumnCount(1)
        self.header().close()
        self.header().setStretchLastSection(False)
        self.header().setSectionResizeMode(
            QtWidgets.QHeaderView.ResizeToContents)
        self.itemDoubleClicked.connect(self._item_clicked)

        self.equipment_table = equipment_table
        self.connection_table = connection_table
        self.skip_names = ('Alias', 'Asset Number', 'Description',
                           'Latest Report Number', 'Model', 'Serial')
        self.rename_map = {'Date Calibrated': 'Year Calibrated'}
        self.create_top_level()

    def create_top_level(self):
        top_level_names = []
        for name in self.equipment_table.header:
            if name in self.skip_names:
                continue
            if name in self.rename_map:
                name = self.rename_map[name]
            top_level_names.append(name)

        top_level_names.extend(['Backend',
                                'Interface'])  # for ConnectionRecord's

        for item in sorted(top_level_names):
            QtWidgets.QTreeWidgetItem(self, [item])

    def populate_tree(self):
        self.clear()
        self.create_top_level()

        for index in range(self.topLevelItemCount()):
            item = self.topLevelItem(index)
            name = item.text(0)
            if name == 'Manufacturer':
                values = {}
                for record in self.equipment_table.records_all:
                    if record.manufacturer and record.manufacturer not in values:
                        values[record.manufacturer] = [record.model]
                    else:
                        if record.model and record.model not in values[
                                record.manufacturer]:
                            values[record.manufacturer].append(record.model)
                item.setText(0, name + ' ({})'.format(len(values)))
                for manufacturer in sorted(values):
                    model_item = QtWidgets.QTreeWidgetItem(
                        item, [manufacturer])
                    for model in sorted(values[manufacturer]):
                        QtWidgets.QTreeWidgetItem(model_item, [model])
            elif name == 'Year Calibrated':
                years = []
                for record in self.equipment_table.records_all:
                    year = record.date_calibrated.year
                    if year > 1 and year not in years:
                        years.append(year)
                item.setText(0, name + ' ({})'.format(len(years)))
                for year in sorted(years)[::-1]:
                    QtWidgets.QTreeWidgetItem(item, [str(year)])
            elif name == 'Connection':
                bools = {'True': 0, 'False': 0}
                for record in self.equipment_table.records_all:
                    bools[str(record.connection is not None)] += 1
                item.setText(0, name + ' (2)')
                for key in sorted(bools):
                    QtWidgets.QTreeWidgetItem(item, [key])
            elif name == 'Calibration Cycle':
                cycles = []
                for record in self.equipment_table.records_all:
                    if record.calibration_cycle == 0:
                        continue
                    if int(record.calibration_cycle
                           ) == record.calibration_cycle:
                        cycle = int(record.calibration_cycle)
                    else:
                        cycle = record.calibration_cycle
                    if cycle not in cycles:
                        cycles.append(cycle)
                item.setText(0, name + ' ({})'.format(len(cycles)))
                for c in sorted(cycles):
                    QtWidgets.QTreeWidgetItem(item, [str(c)])
            else:
                if name == 'Backend' or name == 'Interface':
                    values = self._get_distinct_connection_records(name)
                else:
                    values = self._get_distinct_equipment_records(name)
                item.setText(0, name + ' ({})'.format(len(values)))
                for value in sorted(values):
                    QtWidgets.QTreeWidgetItem(item, [value])

    def _get_distinct_equipment_records(self, name):
        out = []
        attrib = name.lower().replace(' ', '_')
        for record in self.equipment_table.records_all:
            value = u'{}'.format(getattr(record, attrib))
            if value and value not in out:
                out.append(value)
        return out

    def _get_distinct_connection_records(self, name):
        out = []
        attrib = name.lower().replace(' ', '_')
        for record in self.connection_table.records_all:
            value = getattr(record, attrib).name
            if value and value not in out:
                out.append(value)
        return out

    def _item_clicked(self, item, column):
        num_parents = 0
        parent = item.parent()
        while parent is not None:
            parent = parent.parent()
            num_parents += 1

        if num_parents == 0:  # then a top-level item was clicked
            return

        if num_parents == 1:
            attrib_name = item.parent().text(column).split(
                ' (')[column].lower().replace(' ', '_')
            text = u'{}={}'.format(attrib_name, item.text(column))
        else:
            attrib_name = item.parent().parent().text(column).split(
                ' (')[column].lower().replace(' ', '_')
            text = u'{}={}, model={}'.format(attrib_name,
                                             item.parent().text(column),
                                             item.text(column))

        self.sig_selected.emit(text)
Esempio n. 15
0
def test_rescale_icon():
    # the actual size of 'gamma.png'
    size = QtCore.QSize(191, 291)

    icon = convert.to_qicon('gamma.png')
    sizes = icon.availableSizes()
    assert len(sizes) == 1
    assert sizes[0].width() == size.width()
    assert sizes[0].height() == size.height()

    new_size = convert.rescale_icon(icon, 2.6).size()
    assert new_size.width() == int(size.width() * 2.6)
    assert new_size.height() == int(size.height() * 2.6)

    new_size = convert.rescale_icon(icon, 150).size()
    assert new_size.width() == int(
        (150. / float(size.height())) * size.width())
    assert new_size.height() == 150

    new_size = convert.rescale_icon(
        icon, 300, aspect_mode=Qt.KeepAspectRatioByExpanding).size()
    assert new_size.width() == 300
    assert new_size.height() == int(
        (300. / float(size.width())) * size.height())

    size2 = (150, 200)
    new_size = convert.rescale_icon(icon,
                                    size2,
                                    aspect_mode=Qt.IgnoreAspectRatio).size()
    assert new_size.width() == size2[0]
    assert new_size.height() == size2[1]
    new_size = convert.rescale_icon(icon, size2).size()
    assert new_size.width() == int(size2[1] * size.width() /
                                   float(size.height()))
    assert new_size.height() == size2[1]

    # passing different objects does not raise an error
    if sys.platform == 'win32' and has_pythonnet():
        assert isinstance(convert.rescale_icon('explorer|0', 1.0),
                          QtGui.QPixmap)
    assert isinstance(
        convert.rescale_icon(QtWidgets.QStyle.SP_TitleBarMenuButton, 1.0),
        QtGui.QPixmap)
    assert isinstance(convert.rescale_icon(25, 1.0), QtGui.QPixmap)
    assert isinstance(convert.rescale_icon(icon.pixmap(size), 1.0),
                      QtGui.QPixmap)
    assert isinstance(convert.rescale_icon(icon.pixmap(size).toImage(), 1.0),
                      QtGui.QPixmap)

    if sys.platform == 'win32' and has_pythonnet():
        with pytest.raises(TypeError, match=r'Unsupported "size"'):
            convert.rescale_icon('explorer|0', None)

    # if a list/tuple then must contain 2 elements
    for item in [(), [], (256, ), [
            256,
    ], (256, 256, 256), [256, 256, 256]]:
        with pytest.raises(
                ValueError,
                match=r'The size must be in the form \(width, height\)'):
            convert.rescale_icon(icon, item)