Пример #1
0
    def run(self):
        """ Run the model synchronously.
        Shows a modal dialog until the run completes.
        Returns the dialog.
        """
        runner = self.runner
        gui_handler = lambda *args: deferred_call(self.handle_error, *args)
        runner.error_handler = gui_handler
        dialog = RunDialog(parent=self.parent,
                           title='Running model...',
                           text='Please wait while the model runs.')
        dialog.observe('rejected', lambda change: runner.cancel())
        dialog.show()
        event_loop = QtCore.QEventLoop()
        timer = QtCore.QTimer()

        def start_run():
            runner.run()
            timer.setInterval(50)
            timer.timeout.connect(check_loop)
            timer.start()

        def check_loop():
            dialog.output = runner.output()
            if not runner.running:
                timer.stop()
                event_loop.quit()

        timed_call(50, start_run)
        event_loop.exec_()
        dialog.accept()
        return dialog
Пример #2
0
    def __init__(self, proxy, parent, flags=QtCore.Qt.Widget):
        """ Initialize a QWindowDialog.
 
         Parameters
         ----------
         parent : QWidget, optional
             The parent of the dialog.
        """
        super(QWindowDialog, self).__init__(parent, flags)
        # PySide2 segfaults
        self._proxy_ref = None if QT_API in 'pyside2' else atomref(proxy)
        self._expl_min_size = QtCore.QSize()
        self._expl_max_size = QtCore.QSize()
        layout = QWindowLayout()
        layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize)
        self.setLayout(layout)
Пример #3
0
    def delete_widget(self, widget, timeout=1.0):
        """Runs the real Qt event loop until the widget provided has been
        deleted.  Raises ConditionTimeoutError on timeout.

        Parameters
        ----------
        widget : QObject
            The widget whose deletion will stop the event loop.

        timeout : float
            Number of seconds to run the event loop in the case that the
            widget is not deleted.

        """
        timer = QtCore.QTimer()
        timer.setSingleShot(True)
        timer.setInterval(timeout * 1000)
        timer.timeout.connect(self.qt_app.quit)
        widget.destroyed.connect(self.qt_app.quit)
        yield
        timer.start()
        self.qt_app.exec_()
        if not timer.isActive():
            # We exited the event loop on timeout
            raise ConditionTimeoutError(
                'Could not destroy widget before timeout: {!r}'.format(widget))
Пример #4
0
    def __init__(self, parent, delimiters, entries, entries_updater):

        super(QDelimitedCompleter, self).__init__(parent)

        self.delimiters = delimiters
        if isinstance(parent, QtWidgets.QLineEdit):
            self.text_getter = parent.text
            self.cursor_pos = parent.cursorPosition
            self.insert_text = parent.insert
            parent.textChanged[str].connect(self.text_changed)
            self.completionNeeded.connect(self.complete)
        elif isinstance(parent, QtWidgets.QTextEdit):
            parent.textChanged.connect(self.text_changed)
            self.cursor_pos = lambda: parent.textCursor().position()
            self.insert_text =\
                lambda text: parent.textCursor().insertText(text)
            self.text_getter = parent.toPlainText
            self.completionNeeded.connect(self._text_edit_complete)
        else:
            msg = 'Parent of QtCompleter must QLineEdit or QTextEdit, not {}'
            raise ValueError(msg.format(parent))

        self.setCaseSensitivity(QtCore.Qt.CaseSensitive)
        self.setModel(QtCore.QStringListModel(entries, self))

        self.activated[str].connect(self.complete_text)
        self.setWidget(parent)

        self._upddate_entries = True
        self._popup_active = False
        self.entries_updater = entries_updater
Пример #5
0
    def on_paint(self, painter, style_option, widget=None):
        lod = style_option.levelOfDetailFromTransform(painter.worldTransform())

        # painting circle
        painter.setBrush(self.color_background)
        painter.setPen(self.pen_outline)
        painter.drawEllipse(-self.radius, -self.radius, 2 * self.radius,
                            2 * self.radius)

        if self.show_label:
            painter.setFont(self.font_label)
            painter.setPen(self.pen_label)
            is_left = self.socket_position in (SocketPosition.LEFT_BOTTOM,
                                               SocketPosition.LEFT_TOP)

            alignment = QtCore.Qt.AlignVCenter
            if is_left:
                alignment |= QtCore.Qt.AlignLeft
            else:
                alignment |= QtCore.Qt.AlignRight

            node = self.parent()
            width = node.width / 2 - self.radius - self.outline_width
            height = self.radius * 2

            offset = 2 * self.radius + self.outline_width
            x = offset if is_left else -width - offset
            y = -self.radius

            rect = QtCore.QRectF(x, y, width, height)

            painter.drawText(rect, alignment, self.name)
Пример #6
0
 def boundingRect(self):
     p = self.proxy
     return QtCore.QRectF(
         -p.radius - p.outline_width,
         -p.radius - p.outline_width,
         2 * (p.radius + p.outline_width),
         2 * (p.radius + p.outline_width),
     )
Пример #7
0
    def activate_proxy(self):
        super(ToolBar, self).activate_proxy()

        widget = self.proxy.widget
        widget.setWindowTitle(self.title)

        # XXX: Work around Qt bug on Retina displays. To prevent toolbars being
        # twice the correct size, set the toolbar size manually.
        if sys.platform == 'darwin':
            widget.setIconSize(QtCore.QSize(32, 32))
Пример #8
0
    def calcPath(self):
        edge_type = self.proxy.edge_type
        if edge_type == EdgeType.EDGE_TYPE_DIRECT:
            path = QtGui.QPainterPath(
                QtCore.QPointF(self.proxy.pos_source.x,
                               self.proxy.pos_source.y))
            path.lineTo(self.proxy.pos_destination.x,
                        self.proxy.pos_destination.y)
            return path

        elif edge_type == EdgeType.EDGE_TYPE_BEZIER:
            s = self.proxy.pos_source
            d = self.proxy.pos_destination
            dist = (d.x - s.x) * 0.5

            cpx_s = +dist
            cpx_d = -dist
            cpy_s = 0
            cpy_d = 0

            if self.proxy.start_socket is not None:
                sspos = self.proxy.start_socket.socket_position

                if (s.x > d.x and sspos in (SocketPosition.RIGHT_TOP, SocketPosition.RIGHT_BOTTOM)) \
                        or (s.x < d.x and sspos in (SocketPosition.LEFT_BOTTOM, SocketPosition.LEFT_TOP)):
                    cpx_d *= -1
                    cpx_s *= -1

                    cpy_d = ((s.y - d.y) / math.fabs(
                        (s.y - d.y) if (s.y - d.y) != 0 else 0.00001)
                             ) * self.proxy.edge_roundness
                    cpy_s = ((d.y - s.y) / math.fabs(
                        (d.y - s.y) if (d.y - s.y) != 0 else 0.00001)
                             ) * self.proxy.edge_roundness

            path = QtGui.QPainterPath(
                QtCore.QPointF(self.proxy.pos_source.x,
                               self.proxy.pos_source.y))
            path.cubicTo(s.x + cpx_s, s.y + cpy_s, d.x + cpx_d, d.y + cpy_d,
                         self.proxy.pos_destination.x,
                         self.proxy.pos_destination.y)

            return path
Пример #9
0
 def init_signal(self):
     """allow clean shutdown on sigint"""
     signal.signal(signal.SIGINT, lambda sig, frame: self.exit(-2))
     # need a timer, so that QApplication doesn't block until a real
     # Qt event fires (can require mouse movement)
     # timer trick from http://stackoverflow.com/q/4938723/938949
     timer = QtCore.QTimer()
     # Let the interpreter run each 200 ms:
     timer.timeout.connect(lambda: None)
     timer.start(200)
     # hold onto ref, so the timer doesn't get cleaned up
     self._sigint_timer = timer
Пример #10
0
    def __init__(self, proxy, parent=None):
        if QtOGLWidget._ShareWidget is None:
            QtOGLWidget._ShareWidget = QtOpenGL.QGLWidget()
        super(QtOGLWidget, self).__init__(parent, QtOGLWidget._ShareWidget)

        self.proxy = proxy

        self.size = QtCore.QSize(400, 300)
        # eventually handle repeating keys with timer as in pyqtgraph GLViewWidget

        self.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.makeCurrent()
Пример #11
0
    def event_loop_until_condition(self, condition, timeout=10.0):
        """Runs the real Qt event loop until the provided condition evaluates
        to True.

        Raises ConditionTimeoutError if the timeout occurs before the condition
        is satisfied.

        Parameters
        ----------
        condition : callable
            A callable to determine if the stop criteria have been met. This
            should accept no arguments.

        timeout : float
            Number of seconds to run the event loop in the case that the trait
            change does not occur.

        """
        def handler():
            if condition():
                self.qt_app.quit()

        condition_timer = QtCore.QTimer()
        condition_timer.setInterval(50)
        condition_timer.timeout.connect(handler)
        timeout_timer = QtCore.QTimer()
        timeout_timer.setSingleShot(True)
        timeout_timer.setInterval(timeout * 1000)
        timeout_timer.timeout.connect(self.qt_app.quit)
        timeout_timer.start()
        condition_timer.start()
        try:
            self.qt_app.exec_()
            if not timeout_timer.isActive():
                # We exited the event loop on timeout
                raise ConditionTimeoutError('Timed out waiting for condition')
        finally:
            timeout_timer.stop()
            condition_timer.stop()
Пример #12
0
    def paintEvent(self, event):
        if self._inited:
            self._display.Context.UpdateCurrentViewer()
            # important to allow overpainting of the OCC OpenGL context in Qt
            self.swapBuffers()

        if self._drawbox:
            self.makeCurrent()
            painter = QtGui.QPainter(self)
            painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0), 1))
            rect = QtCore.QRect(*self._drawbox)
            painter.drawRect(rect)
            painter.end()
            self.doneCurrent()
    def on_draw_background(self, painter, rect):
        if not self.show_background:
            return

        # here we create our grid
        left = int(math.floor(rect.left()))
        right = int(math.ceil(rect.right()))
        top = int(math.floor(rect.top()))
        bottom = int(math.ceil(rect.bottom()))

        first_left = left - (left % self.background_grid_size)
        first_top = top - (top % self.background_grid_size)

        # compute all lines to be drawn
        lines_light, lines_dark = [], []
        for x in range(first_left, right, self.background_grid_size):
            if x % (self.background_grid_size *
                    self.background_grid_squares) != 0:
                lines_light.append(QtCore.QLine(x, top, x, bottom))
            else:
                lines_dark.append(QtCore.QLine(x, top, x, bottom))

        for y in range(first_top, bottom, self.background_grid_size):
            if y % (self.background_grid_size *
                    self.background_grid_squares) != 0:
                lines_light.append(QtCore.QLine(left, y, right, y))
            else:
                lines_dark.append(QtCore.QLine(left, y, right, y))

        # draw the lines
        if lines_light:
            painter.setPen(self.pen_light)
            painter.drawLines(*lines_light)

        if lines_dark:
            painter.setPen(self.pen_dark)
            painter.drawLines(*lines_dark)
Пример #14
0
 def splitAtPercent(self, t):
     paths = []
     path = QtGui.QPainterPath()
     i = 0
     while i < self.elementCount():
         e = self.elementAt(i)
         if e.type == ElementType.MoveToElement:
             if not path.isEmpty():
                 paths.append(path)
             path = QtGui.QPainterPath(QtCore.QPointF(e.x, e.y))
         elif e.type == ElementType.LineToElement:
             path.lineTo(QtCore.QPointF(e.x, e.y))
         elif e.type == ElementType.CurveToElement:
             e1, e2 = self.elementAt(i + 1), self.elementAt(i + 2)
             path.cubicTo(QtCore.QPointF(e.x, e.y),
                          QtCore.QPointF(e1.x, e1.y),
                          QtCore.QPointF(e2.x, e2.y))
             i += 2
         else:
             raise ValueError("Invalid element type %s" % (e.type, ))
         i += 1
     if not path.isEmpty():
         paths.append(path)
     return paths
Пример #15
0
class PushSinkAdapter(QtCore.QObject):

    dataReady = QtCore.Signal(['PyQt_PyObject'], name='dataReady')

    def __init__(self, sink):
        super(PushSinkAdapter, self).__init__()

        self.sink = sink
        self._time = None
        self._value = None

    def cb_handler(self, m):
        try:
            self._time = m.time()
            self._value = m
            self.dataReady.emit(self._time)
        except Exception, e:
            log.exception(e)
Пример #16
0
 def set_language(self, language):
     try:
         language = getattr(QtCore.QLocale, language, 'system')
         if isinstance(language, int):
             locale = QtCore.QLocale(language).name()
         elif callable(language):
             locale = language().name()
         else:
             locale = QtCore.QLocale.system().name()
         root_dir = os.path.dirname(os.path.dirname(__file__))
         path = os.path.join(root_dir, "res", "translations", locale)
         if self.translator.load(path):
             log.warning("Setting locale: %s" % locale)
             self.application._qapp.installTranslator(self.translator)
         else:
             log.warning("Translations not found at %s" % path)
     except Exception as e:
         log.exception(e)
Пример #17
0
    def __init__(self,
                 key_event_handler=None,
                 mouse_event_handler=None,
                 cam_width=1024,
                 cam_height=768,
                 cam_near=0.01,
                 cam_far=10.0,
                 camera_intrinsics=None,
                 parent=None):

        if QtVirtualCameraWidget.ShareWidget is None:
            ## create a dummy widget to allow sharing objects (textures, shaders, etc) between views
            QtVirtualCameraWidget.ShareWidget = QtOpenGL.QGLWidget()

        QtOpenGL.QGLWidget.__init__(self, parent,
                                    QtVirtualCameraWidget.ShareWidget)

        self.setFocusPolicy(QtCore.Qt.ClickFocus)

        self.bgtexture = visualization.BackgroundImage()
        self.camera_intrinsics = camera_intrinsics
        self.camera_pose = None

        self.camera_width = float(cam_width)
        self.camera_height = float(cam_height)
        self.camera_near = float(cam_near)
        self.camera_far = float(cam_far)

        self.screen_width = cam_width
        self.screen_height = cam_height

        self.items = []

        self.key_event_handler = key_event_handler
        self.mouse_event_handler = mouse_event_handler
        self.noRepeatKeys = [
            QtCore.Qt.Key_Right, QtCore.Qt.Key_Left, QtCore.Qt.Key_Up,
            QtCore.Qt.Key_Down, QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown
        ]
        self.keysPressed = {}
        self.keyTimer = QtCore.QTimer()
        self.keyTimer.timeout.connect(self.evalKeyState)

        self.makeCurrent()
Пример #18
0
    def startDrag(self, actions):
        """ Reimplemented to start the drag of a tree widget item.

        """
        nid = self.currentItem()
        if nid is None:
            return

        self._dragging = nid

        _, node, obj = self._controller._get_node_data(nid)

        # Convert the item being dragged to MIME data.
        drag_object = node.get_drag_object(obj)
        md = PyMimeData.coerce(drag_object)

        # Render the item being dragged as a pixmap.
        nid_rect = self.visualItemRect(nid)
        rect = nid_rect.intersected(self.viewport().rect())
        pm = QtGui.QPixmap(rect.size())
        pm.fill(self.palette().base().color())
        painter = QtGui.QPainter(pm)

        option = self.viewOptions()
        option.state |= QtWidgets.QStyle.State_Selected
        option.rect = QtCore.QRect(nid_rect.topLeft() -
                                   rect.topLeft(), nid_rect.size())
        self.itemDelegate().paint(painter, option, self.indexFromItem(nid))

        painter.end()

        # Calculate the hotspot so that the pixmap appears on top of the
        # original item.
        hspos = self.viewport().mapFromGlobal(QtGui.QCursor.pos()) - \
            nid_rect.topLeft()

        # Start the drag.
        drag = QtGui.QDrag(self)
        drag.setMimeData(md)
        drag.setPixmap(pm)
        drag.setHotSpot(hspos)
        drag.exec_(actions)
Пример #19
0
class OutPort(Port):

    dataReady = QtCore.Signal(['PyQt_PyObject'], name='dataReady')

    def __init__(self, parent, name):
        super(Port, self).__init__(parent, name)

    def send(self, value):
        self.dataReady.emit(value)

    def subscribe(self, inport):
        info = inport.get_info()
        if info.queued:
            return self.dataReady.connect(inport.handle_receive,
                                          QtCore.Qt.QueuedConnection)
        else:
            return self.dataReady.connect(inport.handle_receive)

    def unsubscribe(self, inport):
        raise NotImplemented
Пример #20
0
    def __init__(self, e, ids=None):
        """
        Creates a QtPainterPath from an SVG document applying all transforms. 
        
        Does NOT include any styling.
        
        Parameters
        ----------
            e: Element or string
                An lxml etree.Element or an argument to pass to etree.parse()
            ids: List
                List of node ids to include. If not given all will be used.
        """
        self.isParentSvg = not isinstance(e, EtreeElement)
        self.ids = ids or []
        if self.isParentSvg:
            self._doc = etree.parse(e)
            self._svg = self._doc.getroot()
            self.viewBox = QtCore.QRectF(0, 0, -1, -1)

        super(QtSvgDoc, self).__init__(self._svg)
Пример #21
0
    def text_changed(self, text=None):
        """Callback handling the text being edited on the parent.

        """
        if not text:
            text = self.text_getter()

        if self._upddate_entries and self.entries_updater:
            entries = self.entries_updater()
            self.setModel(QtCore.QStringListModel(entries, self))
            self._upddate_entries = False

        all_text = uni(text)
        text = all_text[:self.cursor_pos()]
        split = text.split(self.delimiters[0])
        prefix = split[-1].strip()

        if len(split) > 1:
            self.setCompletionPrefix(prefix)
            self.completionNeeded.emit()
        elif self.popup().isVisible():
            self.popup().hide()
Пример #22
0
    def run(self):
        """ Run the UI workbench application.

        This method will load the core and ui plugins and start the
        main application event loop. This is a blocking call which
        will return when the application event loop exits.

        """
        InkcutWorkbench._instance = self

        with enaml.imports():
            from enaml.workbench.core.core_manifest import CoreManifest
            from enaml.workbench.ui.ui_manifest import UIManifest
            from inkcut.core.manifest import InkcutManifest
            #from inkcut.settings.manifest import SettingsManifest

        self.register(CoreManifest())
        self.register(UIManifest())
        self.register(InkcutManifest())
        #self.register(SettingsManifest())
        #: Init the ui
        ui = self.get_plugin('enaml.workbench.ui')
        ui.show_window()

        # Make sure ^C keeps working
        signal.signal(signal.SIGINT, signal.SIG_DFL)

        #: Start the core plugin
        plugin = self.get_plugin('inkcut.core')

        locale = QtCore.QLocale.system().name()
        qtTranslator = QtCore.QTranslator()
        if qtTranslator.load("inkcut/res/translations/" + locale):
            self.application._qapp.installTranslator(qtTranslator)

        ui.start_application()
Пример #23
0
    def __init__(self, e, ids=None):
        """
        Creates a QtPainterPath from an SVG document applying all transforms. 
        
        Does NOT include any styling.
        
        Parameters
        ----------
            e: Element or string
                An lxml etree.Element or an argument to pass to etree.parse()
            ids: List
                List of node ids to include. If not given all will be used.
        """
        self.isParentSvg = not isinstance(e, EtreeElement)
        if self.isParentSvg:
            self._doc = etree.parse(e)
            self._svg = self._doc.getroot()
            if ids:
                nodes = set()
                xpath = self._svg.xpath
                for node_id in ids:
                    nodes.update(set(xpath('//*[@id="%s"]' % node_id)))

                # Find all nodes and their parents
                valid_nodes = set()
                for node in nodes:
                    valid_nodes.add(node)
                    parent = node.getparent()
                    while parent:
                        valid_nodes.add(parent)
                        parent = parent.getparent()
                self._nodes = valid_nodes

            self.viewBox = QtCore.QRectF(0, 0, -1, -1)

        super(QtSvgDoc, self).__init__(self._svg, self._nodes)
Пример #24
0
    def _job_changed(self, change):
        """ Recreate an instance of of the plot using the current settings 
        
        """
        if self._blocked:
            return

        if change['name'] == 'copies':
            self._desired_copies = self.copies

        #try:
        model = QtGui.QPainterPath()

        if not self.path:
            return

        path = self._create_copy()

        # Update size
        bbox = path.boundingRect()
        self.size = [bbox.width(), bbox.height()]

        # Create copies
        c = 0
        points = self._copy_positions_iter(path)

        if self.auto_copies:
            self.stack_size = self._compute_stack_sizes(path)
            if self.stack_size[0]:
                copies_left = self.copies % self.stack_size[0]
                if copies_left:  # not a full stack
                    with self.events_suppressed():
                        self.copies = self._desired_copies
                        self.add_stack()

        while c < self.copies:
            x, y = next(points)
            model.addPath(path * QtGui.QTransform.fromTranslate(x, -y))
            c += 1

        # Create weedline
        if self.plot_weedline:
            self._add_weedline(model, self.plot_weedline_padding)

        # Move to 0,0
        bbox = model.boundingRect()
        p = bbox.bottomLeft()
        tx, ty = -p.x(), -p.y()

        # Center or set to padding
        tx += ((self.material.width() - bbox.width()) /
               2.0 if self.align_center[0] else self.material.padding_left)
        ty += (-(self.material.height() - bbox.height()) /
               2.0 if self.align_center[1] else -self.material.padding_bottom)

        t = QtGui.QTransform.fromTranslate(tx, ty)

        model = model * t

        end_point = (QtCore.QPointF(
            0, -self.feed_after + model.boundingRect().top())
                     if self.feed_to_end else QtCore.QPointF(0, 0))
        model.moveTo(end_point)

        # Set new model
        self.model = model  #.simplified()
Пример #25
0
class CompleterLineEdit(QtGui.QLineEdit):
    """
    """
    completionNeeded = QtCore.Signal(str)

    def __init__(self, parent, delimiters, entries, entries_updater):

        self.delimiters = delimiters

        super(CompleterLineEdit, self).__init__(parent)
        self.textChanged[str].connect(self.text_changed)
        self.completer = QtGui.QCompleter(self)
        self.completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.completer.setModel(QtGui.QStringListModel(entries,
                                                       self.completer))

        self.completionNeeded.connect(self.completer.complete)
        self.completer.activated[str].connect(self.complete_text)
        self.completer.setWidget(self)

        self._upddate_entries = True
        self.editingFinished.connect(self.on_editing_finished)
        self.entries_updater = entries_updater

    def text_changed(self, text):
        """
        """
        if self._upddate_entries and self.entries_updater:
            entries = self.entries_updater()
            self.completer.setModel(
                QtGui.QStringListModel(entries, self.completer))
            self._upddate_entries = False

        all_text = unicode(text)
        text = all_text[:self.cursorPosition()]
        split = text.split(self.delimiters[0])
        prefix = split[-1].strip()

        if len(split) > 1:
            self.completer.setCompletionPrefix(prefix)
            self.completionNeeded.emit(prefix)

        self.string = text

    def complete_text(self, text):
        """
        """
        cursor_pos = self.cursorPosition()
        before_text = unicode(self.text())[:cursor_pos]
        after_text = unicode(self.text())[cursor_pos:]
        prefix_len = len(before_text.split(self.delimiters[0])[-1].strip())

        if after_text.startswith(self.delimiters[1]):
            self.setText(before_text[:cursor_pos - prefix_len] + text +
                         after_text)
        else:
            self.setText(before_text[:cursor_pos - prefix_len] + text +
                         self.delimiters[1] + after_text)

        self.string = before_text[:cursor_pos - prefix_len] + text +\
            self.delimiters[1] + after_text

        self.setCursorPosition(cursor_pos - prefix_len + len(text) + 2)
        self.textEdited.emit(self.string)

    def on_editing_finished(self):
        self._upddate_entries = True

    def _update_entries(self, entries):
        self.completer.setModel(QtGui.QStringListModel(entries,
                                                       self.completer))
Пример #26
0
def qInitResources():
    QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
Пример #27
0
def qCleanupResources():
    QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
Пример #28
0
 def parse(self, e):
     c = QtCore.QPointF(*map(self.parseUnit, (e.attrib.get('cx', 0),
                                              e.attrib.get('cy', 0))))
     r = self.parseUnit(e.attrib.get('r', 0))
     self.addEllipse(c, r, r)
Пример #29
0
 def _default_area(self):
     return QtCore.QRectF(0, 0, self.size[0], self.size[1])
Пример #30
0
 def available_area(self):
     x, y = self.padding_left, self.padding_bottom
     w, h = (self.size[0] - (self.padding_right + self.padding_left),
             self.size[1] - (self.padding_bottom + self.padding_top))
     return QtCore.QRectF(x, y, w, h)
Пример #31
0
    def process(self, model):
        """  Process the path model of a job and return each command
        within the job.

        Parameters
        ----------
            model: QPainterPath
                The path to process

        Returns
        -------
            generator: A list or generator object that yields each command
             to invoke on the device and the distance moved. In the format
             (distance, cmd, args, kwargs)

        """
        config = self.config

        #: Previous point
        _p = QtCore.QPointF(self.origin[0], self.origin[1])

        #: Do a final translation since Qt's y axis is reversed
        t = QtGui.QTransform.fromScale(1, -1)
        model = model * t

        #: Determine if interpolation should be used
        skip_interpolation = (self.connection.always_spools or config.spooled
                              or not config.interpolate)

        # speed = distance/seconds
        # So distance/speed = seconds to wait
        step_size = config.step_size
        if not skip_interpolation and step_size <= 0:
            raise ValueError("Cannot have a step size <= 0!")
        try:
            # Apply device filters
            for f in self.filters:
                log.debug(" filter | Running {} on model".format(f))
                model = f.apply_to_model(model)

            # Some versions of Qt seem to require a value in toSubpathPolygons
            m = QtGui.QTransform.fromScale(1, 1)
            polypath = model.toSubpathPolygons(m)

            # Apply device filters to polypath
            for f in self.filters:
                log.debug(" filter | Running {} on polypath".format(f))
                polypath = f.apply_to_polypath(polypath)

            for path in polypath:

                #: And then each point within the path
                #: this is a polygon
                for i, p in enumerate(path):

                    #: Head state
                    # 0 move, 1 cut
                    z = 0 if i == 0 else 1

                    #: Make a subpath
                    subpath = QtGui.QPainterPath()
                    subpath.moveTo(_p)
                    subpath.lineTo(p)

                    #: Update the last point
                    _p = p

                    #: Total length
                    l = subpath.length()

                    #: If the device does not support streaming
                    #: the path interpolation is skipped entirely
                    if skip_interpolation:
                        x, y = p.x(), p.y()
                        yield (l, self.move, ([x, y, z], ), {})
                        continue

                    #: Where we are within the subpath
                    d = 0

                    #: Interpolate path in steps of dl and ensure we get
                    #: _p and p (t=0 and t=1)
                    #: This allows us to cancel mid point
                    while d <= l:
                        #: Now set d to the next point by step_size
                        #: if the end of the path is less than the step size
                        #: use the minimum of the two
                        dl = min(l - d, step_size)

                        #: Now find the point at the given step size
                        #: the first point d=0 so t=0, the last point d=l so t=1
                        t = subpath.percentAtLength(d)
                        sp = subpath.pointAtPercent(t)
                        #if d == l:
                        #    break  #: Um don't we want to send the last point??

                        #: -y because Qt's axis is from top to bottom not bottom
                        #: to top
                        x, y = sp.x(), sp.y()
                        yield (dl, self.move, ([x, y, z], ), {})

                        #: When we reached the end but instead of breaking above
                        #: with a d < l we do it here to ensure we get the last
                        #: point
                        if d == l:
                            #: We reached the end
                            break

                        #: Add step size
                        d += dl

            #: Make sure we get the endpoint
            ep = model.currentPosition()
            yield (0, self.move, ([ep.x(), ep.y(), 0], ), {})
        except Exception as e:
            log.error("device | processing error: {}".format(
                traceback.format_exc()))
            raise e
Пример #32
0
    def process(self, model):
        """  Process the path model of a job and return each command
        within the job.

        Parameters
        ----------
            model: QPainterPath
                The path to process

        Returns
        -------
            generator: A list or generator object that yields each command
             to invoke on the device and the distance moved. In the format
             (distance, cmd, args, kwargs)

        """
        config = self.config

        # Previous point
        _p = QtCore.QPointF(self.origin[0], self.origin[1])

        # Do a final translation since Qt's y axis is reversed from svg's
        # It should now be a bbox of (x=0, y=0, width, height)
        # this creates a copy
        model = model * QtGui.QTransform.fromScale(1, -1)

        # Determine if interpolation should be used
        skip_interpolation = (self.connection.always_spools or config.spooled
                              or not config.interpolate)

        # speed = distance/seconds
        # So distance/speed = seconds to wait
        step_size = config.step_size
        if not skip_interpolation and step_size <= 0:
            raise ValueError("Cannot have a step size <= 0!")
        try:
            # Apply device filters
            for f in self.filters:
                log.debug(" filter | Running {} on model".format(f))
                model = f.apply_to_model(model, job=self)

            # Since Qt's toSubpathPolygons converts curves without accepting
            # a parameter to set the minimum distance between points on the
            # curve, we need to prescale by a "quality factor" before
            # converting then undo the scaling to effectively adjust the
            # number of points on a curve.
            m = QtGui.QTransform.fromScale(config.quality_factor,
                                           config.quality_factor)
            # Some versions of Qt seem to require a value in toSubpathPolygons
            polypath = model.toSubpathPolygons(m)

            if config.quality_factor != 1:
                # Undo the prescaling, if the quality_factor > 1 the curve
                # quality will be improved.
                m_inv = QtGui.QTransform.fromScale(1 / config.quality_factor,
                                                   1 / config.quality_factor)
                polypath = list(map(m_inv.map, polypath))

            # Apply device filters to polypath
            for f in self.filters:
                log.debug(" filter | Running {} on polypath".format(f))
                polypath = f.apply_to_polypath(polypath)

            for path in polypath:

                #: And then each point within the path
                #: this is a polygon
                for i, p in enumerate(path):

                    #: Head state
                    # 0 move, 1 cut
                    z = 0 if i == 0 else 1

                    #: Make a subpath
                    subpath = QtGui.QPainterPath()
                    subpath.moveTo(_p)
                    subpath.lineTo(p)

                    #: Update the last point
                    _p = p

                    #: Total length
                    l = subpath.length()

                    #: If the device does not support streaming
                    #: the path interpolation is skipped entirely
                    if skip_interpolation:
                        x, y = p.x(), p.y()
                        yield (l, self.move, ([x, y, z], ), {})
                        continue

                    #: Where we are within the subpath
                    d = 0

                    #: Interpolate path in steps of dl and ensure we get
                    #: _p and p (t=0 and t=1)
                    #: This allows us to cancel mid point
                    while d <= l:
                        #: Now set d to the next point by step_size
                        #: if the end of the path is less than the step size
                        #: use the minimum of the two
                        dl = min(l - d, step_size)

                        #: Now find the point at the given step size
                        #: the first point d=0 so t=0, the last point d=l so t=1
                        t = subpath.percentAtLength(d)
                        sp = subpath.pointAtPercent(t)
                        #if d == l:
                        #    break  #: Um don't we want to send the last point??

                        x, y = sp.x(), sp.y()
                        yield (dl, self.move, ([x, y, z], ), {})

                        #: When we reached the end but instead of breaking above
                        #: with a d < l we do it here to ensure we get the last
                        #: point
                        if d == l:
                            #: We reached the end
                            break

                        #: Add step size
                        d += dl

            #: Make sure we get the endpoint
            ep = model.currentPosition()
            x, y = ep.x(), ep.y()
            yield (0, self.move, ([x, y, 0], ), {})
        except Exception as e:
            log.error("device | processing error: {}".format(
                traceback.format_exc()))
            raise e