コード例 #1
0
    def paintEvent(self, event):
        """
        Paint the graph.

        :param event:
        :return:
        """

        painter = QPainter(self.viewport())

        # scrollbar values
        current_x = self.horizontalScrollBar().value()
        current_y = self.verticalScrollBar().value()
        # coord translation
        # (0, 0) -> middle of the page
        painter.translate(self.width() / 2 - current_x,
                          self.height() / 2 - current_y)

        painter.setFont(self.workspace.disasm_font)

        topleft_point = self._to_graph_pos(QPoint(0, 0))
        bottomright_point = self._to_graph_pos(
            QPoint(self.width(), self.height()))

        self._draw_edges(painter, topleft_point, bottomright_point)
        self._draw_nodes(painter, topleft_point, bottomright_point)
コード例 #2
0
    def __init__(self, directory, *args, **kwargs):
        self.directory = directory
        self.figures = []

        if 'json_dict' in kwargs:
            self.file_name = kwargs['json_dict']['file_name']

            if 'draw_scale' in kwargs['json_dict']:
                self.draw_scale = kwargs['json_dict']['draw_scale']
            else:
                self.draw_scale = 1.0

            if 'draw_offset' in kwargs['json_dict']:
                self.draw_offset = dict2qpoint(kwargs['json_dict']['draw_offset'])
            else:
                self.draw_offset = QPoint()

            self.figures = [Rectangle(figure=figure_dict['rect']) if figure_dict.keys()[0] == 'rect' else
                            Circle(figure=figure_dict['circle']) if figure_dict.keys()[0] == 'circle' else
                            Polygon(figure=figure_dict['polygon']) for figure_dict in kwargs['json_dict']['figures']]
        else:
            self.draw_scale = 1.0
            self.draw_offset = QPoint()
            self.file_name = kwargs['file_name']

        self.image = None
コード例 #3
0
    def paint(self, painter, point):
        painter.save()

        size = QSize(self.width(), self.height())
        painter.setBrush(self.bg_color)
        painter.drawRoundedRect(QRect(point, size), BLOCK_RADIUS, BLOCK_RADIUS)

        # Рисуем столбцы
        p = QPoint(point) + QPoint(0, BLOCK_RADIUS)
        for c in self.columns:
            p += QPoint(BLOCK_RADIUS, 0)
            c.paint(painter, p)
            p += QPoint(c.width(), 0)

        # Рисуем левые порты
        if len(self.left_pins):
            p = QPoint(point)
            p += QPoint(0, size.height() / (len(self.left_pins) + 1))
            for lp in self.left_pins:
                lp.paint(painter, p)
                p += QPoint(0, size.height() / (len(self.left_pins) + 1))

        # Рисуем правые порты
        if len(self.right_pins):
            p = QPoint(point)
            p += QPoint(size.width(),
                        size.height() / (len(self.right_pins) + 1))
            for rp in self.right_pins:
                rp.paint(painter, p)
                p += QPoint(0, size.height() / (len(self.right_pins) + 1))

        painter.restore()
コード例 #4
0
    def save_image_to(self, path):

        TOP_MARGIN = 50
        LEFT_MARGIN = 50

        # Determine the size of the entire graph
        graph_size = self._graph_size()

        image_size = QSize(graph_size.width() + LEFT_MARGIN * 2,
                           graph_size.height() + TOP_MARGIN * 2
                           )

        image = QImage(image_size, QImage.Format_ARGB32)
        image.fill(Qt.white)  # white background

        painter = QPainter(image)
        painter.translate(TOP_MARGIN, LEFT_MARGIN)
        painter.setRenderHint(QPainter.TextAntialiasing)
        self._paint(painter,
                    QPoint(-TOP_MARGIN, -LEFT_MARGIN),
                    QPoint(image_size.width(), image_size.height())
                    )
        painter.end()

        image.save(path)
コード例 #5
0
def QtRectToPoly(rect):
    x1, y1, x2, y2 = rect.getCoords()
    poly = QPolygon()
    poly.push_back(QPoint(x1, y1))
    poly.push_back(QPoint(x2, y1))
    poly.push_back(QPoint(x2, y2))
    poly.push_back(QPoint(x1, y2))
    return poly
コード例 #6
0
ファイル: editor.py プロジェクト: sherckuith/pinguino-ide
 def getPosPopup(self):
     pos = self.pos()
     pos1 = self.mapToGlobal(pos)
     pos2 = QPoint()
     cRect = self.cursorRect()
     pos2.setX(cRect.x())
     pos2.setY(cRect.y())
     return pos1 + pos2
コード例 #7
0
    def testConstructorQPoint(self):
        topLeft = QPoint(3, 0)
        bottomRight = QPoint(0, 3)

        rect1 = QRect(topLeft, bottomRight)
        rect2 = QRect(topLeft, bottomRight)

        self.assertEqual(rect1, rect2)
コード例 #8
0
 def test_getDict(self):
     r = Rectangle(QPoint(10, 20), QPoint(30, 40))
     self.assertEqual(r.getDict(),
                      {'rect': {
                          'x1': 10,
                          'y1': 20,
                          'x2': 30,
                          'y2': 40
                      }})
コード例 #9
0
 def _calculateMeasures(self):
     self._hor_margin = 4
     self._ver_margin = (self.height() - self._drop_icon.height()) // 2
     self._drop_icon_pos = QPoint(
         self.width() - self._drop_icon.width() - self._hor_margin,
         self._ver_margin)
     self._grad_start = QPoint(self.width() // 2,
                               self.height())  # bottom-up gradient
     self._grad_end = QPoint(self.width() // 2, 0)
コード例 #10
0
    def testFunctionUnit(self):
        r = QRegion(0, 0, 10, 10)
        r2 = QRegion(5, 5, 10, 10)
 
        ru = r.united(r2)
        self.assert_(ru.contains(QPoint(0,0)))
        self.assert_(ru.contains(QPoint(5,5)))
        self.assert_(ru.contains(QPoint(10,10)))
        self.assert_(ru.contains(QPoint(14,14)))
コード例 #11
0
    def mousePressEvent(self, mouse_event):
        if mouse_event.button() == Qt.RightButton:
            if self._spec_index is None:
                print("spec_index is None")
                print(self)
                print(self._running_providers)
                return
            pos = mouse_event.pos()
            items = [
                item for item in self.items(pos)
                if isinstance(item, NodeItem) and item._label.text()
            ]
            if len(items) != 1:
                print("wrong number of things",
                      [x._label.text() for x in items])
                return

            name = items[0]._label.text().rstrip('(default)').strip()
            if name not in self._spec_index.provider_names:
                print(name, "Not in list of providers")
                return
            provider = self._spec_index.providers[name]

            def start_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/start_capability'.format(
                    'capability_server')
                rospy.wait_for_service(service_name)
                start_capability = rospy.ServiceProxy(service_name,
                                                      StartCapability)
                start_capability(provider.implements, name)

            def stop_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/stop_capability'.format(
                    'capability_server')
                rospy.wait_for_service(service_name)
                stop_capability = rospy.ServiceProxy(service_name,
                                                     StopCapability)
                stop_capability(provider.implements)

            if name not in self._running_providers:
                trigger = start_trigger
                msg = "start => "
            else:
                trigger = stop_trigger
                msg = "stop => "

            menu = QMenu()
            action = menu.addAction(msg + name)
            action.triggered.connect(trigger)
            pos = mouse_event.globalPos()
            pos = QPoint(pos.x(), pos.y())
            menu.exec_(pos)
        else:
            InteractiveGraphicsView.mousePressEvent(self, mouse_event)
コード例 #12
0
    def paint(self, painter, point):
        painter.save()

        p = QPoint(point)
        for b in self.blocks:
            b.paint(painter, p)
            p += QPoint(0, 5)
            p += QPoint(0, b.height())

        painter.restore()
コード例 #13
0
def intersection(p1, p2, q1, q2):
    a1 = p2.y() - p1.y()
    b1 = p1.x() - p2.x()
    c1 = a1 * p1.x() + b1 * p1.y()
    a2 = q2.y() - q1.y()
    b2 = q1.x() - q2.x()
    c2 = a2 * q1.x() + b2 * q1.y()
    det = a1 * b2 - a2 * b1
    if not eq(det, 0):
        return QPoint((b2 * c1 - b1 * c2) / det, (a1 * c2 - a2 * c1) / det)
    else:
        return QPoint()
コード例 #14
0
class Mouse(object):
    """"""
    def __init__(self, view):
        self.view = view
        self.pos = QPoint()
        self.last_pos = QPoint()

    def dx(self):
        return self.pos.x() - self.last_pos.x()

    def dy(self):
        return self.pos.y() - self.last_pos.y()
コード例 #15
0
ファイル: common.py プロジェクト: realmhamdy/VisualScrape
 def mouseReleaseEvent(self, mre):
   if mre.button() == Qt.LeftButton:
     final_pos = mre.pos()
     distance = QPoint(final_pos.x() - self._pos_press_start.x(), final_pos.y() - self._pos_press_start.y())
     distance = distance.manhattanLength()
     if distance > QApplication.startDragDistance():
       # then move the widget. But I really want to know whether the new point is to the right or left to the old point
       if final_pos.x() > self._pos_press_start.x():
         self.prev()
       else:
         self.next()
   self.setCursor(Qt.CursorShape.ArrowCursor)
   super(DragEnabledCentralScroller, self).mouseReleaseEvent(mre)
コード例 #16
0
ファイル: plotter.py プロジェクト: Yakisoba007/PyTrigno
 def drawPoints(self, qp):
     ''' draw points for electrode positions and
     their connection lines to the plots
     '''
     qp.setPen(Qt.white)
     qp.setBrush(Qt.white)
     for key, item in self.plots.iteritems():
         pos = item.pos()
         pos = QPoint(pos.x()+item.size().width(), pos.y()+item.size().height())
         qp.drawLine(pos, self.points[int(key)-1])
         qp.drawEllipse(pos, 4,4)
     for pp in self.points:
         qp.drawEllipse(pp, 4,4)
コード例 #17
0
ファイル: Image.py プロジェクト: Ingener74/Small-Screwdriver
    def draw(self, painter, offset=Point()):
        cropped_image, x, y, width, height = self.__getCrop()

        origin_offset = QPoint(self.origin.x + offset.x, self.origin.y + offset.y)

        if self.rotated:
            old_transform = QTransform(painter.transform())
            painter.setTransform(painter.transform().translate(origin_offset.x() + self.crop.size.height,
                                                               origin_offset.y()).rotate(90, Qt.ZAxis))
            painter.drawImage(0, 0, cropped_image)
            painter.setTransform(old_transform)
        else:
            painter.drawImage(origin_offset, cropped_image)
コード例 #18
0
ファイル: slideshow.py プロジェクト: realmhamdy/VisualScrape
 def animateWidget(self, widget, distance, direction):
     widget_anim = QPropertyAnimation(widget, "geometry")
     cur_geom = widget.geometry()
     next_geom = QRect(cur_geom)
     if direction == self.LEFT:
         next_geom.moveTo(widget.pos() - QPoint(distance, 0))
     elif direction == self.RIGHT:
         next_geom.moveTo(widget.pos() + QPoint(distance, 0))
     widget_anim.setDuration(self.ANIM_DURATION)
     widget_anim.setEasingCurve(self.EASING)
     widget_anim.setStartValue(cur_geom)
     widget_anim.setEndValue(next_geom)
     self._anim_grp.addAnimation(widget_anim)
コード例 #19
0
ファイル: human_event.py プロジェクト: juanchitot/jaimeboot
 def scrollTo(self):
     l = len(self.returns_stack) 
     self.logger.debug('scrollTo')
     if l and isinstance(self.returns_stack[l-1],QPoint):
         viewport = Jaime.instance.view.page().viewportSize()            
         pos = self.returns_stack.pop()            
         scroll_to_pos = QPoint(0,0)
         if pos.x() >= viewport.width():
             scroll_to_pos.setX(int ( pos.x() - ( viewport.width() / 2)))
         if pos.y() >= viewport.height():
             scroll_to_pos.setY(int ( pos.y() - ( viewport.height() / 2)))
         self.logger.info('scrollTo, scrolling to  %s' % scroll_to_pos )
         Jaime.instance.view.page().mainFrame().setScrollPosition(scroll_to_pos)
コード例 #20
0
    def __init__(self, *args, **kwargs):

        self.first_point = FirstPoint()
        self.second_point = SecondPoint()
        self.control = Control()

        self.p1 = QPoint()
        self.p2 = QPoint()

        Figure.__init__(self, self.first_point)
        if 'x1' in kwargs and 'y1' in kwargs:
            self.p1 = QPoint(kwargs['x1'], kwargs['y1'])
        if 'x2' in kwargs and 'y2' in kwargs:
            self.p2 = QPoint(kwargs['x2'], kwargs['y2'])
        if 'p1' in kwargs:
            self.p1 = kwargs['p1']
        if 'p2' in kwargs:
            self.p2 = kwargs['p2']
        if len(args) == 2:
            self.p1 = args[0]
            self.p2 = args[1]
        if len(args) == 4:
            self.p1 = QPoint(args[0], args[1])
            self.p2 = QPoint(args[2], args[3])

        if 'figure' in kwargs:
            self.p1 = QPoint(kwargs['figure']['x1'], kwargs['figure']['y1'])
            self.p2 = QPoint(kwargs['figure']['x2'], kwargs['figure']['y2'])
            self.state = self.control
コード例 #21
0
    def show_instruction(self, insn_addr):
        block = self._insn_addr_to_block.get(insn_addr, None)
        if block is not None:
            pos = QPoint(*block.instruction_position(insn_addr))
            pos_ = self._from_graph_pos(pos)

            # is it visible?
            if 0 <= pos_.x() < self.width() and 0 <= pos_.y() < self.height():
                return

            # make it visible
            x, y = pos.x(), pos.y()
            self.horizontalScrollBar().setValue(x - 50)
            self.verticalScrollBar().setValue(y - 50)
コード例 #22
0
    def mousePressEvent(self, mouse_event):
        if mouse_event.button() == Qt.RightButton:
            if self._spec_index is None:
                print("spec_index is None")
                print(self)
                print(self._running_providers)
                return
            pos = mouse_event.pos()
            items = [item for item in self.items(pos) if isinstance(item, NodeItem) and item._label.text()]
            if len(items) != 1:
                print("wrong number of things", [x._label.text() for x in items])
                return

            name = items[0]._label.text().rstrip('(default)').strip()
            if name not in self._spec_index.provider_names:
                print(name, "Not in list of providers")
                return
            provider = self._spec_index.providers[name]

            def start_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/start_capability'.format('capability_server')
                rospy.wait_for_service(service_name)
                start_capability = rospy.ServiceProxy(service_name, StartCapability)
                start_capability(provider.implements, name)

            def stop_trigger():
                # TODO: replace 'capability_server' with user provided server name
                service_name = '/{0}/stop_capability'.format('capability_server')
                rospy.wait_for_service(service_name)
                stop_capability = rospy.ServiceProxy(service_name, StopCapability)
                stop_capability(provider.implements)

            if name not in self._running_providers:
                trigger = start_trigger
                msg = "start => "
            else:
                trigger = stop_trigger
                msg = "stop => "

            menu = QMenu()
            action = menu.addAction(msg + name)
            action.triggered.connect(trigger)
            pos = mouse_event.globalPos()
            pos = QPoint(pos.x(), pos.y())
            menu.exec_(pos)
        else:
            InteractiveGraphicsView.mousePressEvent(self, mouse_event)
コード例 #23
0
ファイル: yame.py プロジェクト: Cloudxtreme/yame
    def parseMarkdown(self):
        """
        Parse the Markdown stuff.
        """
        self.updateStructure()
        if self.sync is False:
            return

        y = self.web.page().mainFrame().scrollPosition().y()
        txt = self.editor.toPlainText().encode('utf-8')

        if txt is '' or None:
            return

        p = Popen([self.parser],
                  stdout=PIPE,
                  stdin=PIPE,
                  stderr=STDOUT,
                  shell=False)
        grep_stdout = p.communicate(input=txt)[0].decode('utf-8')
        path = QUrl.fromUserInput(os.getcwd() + os.sep)
        grep_stdout = grep_stdout.replace('img src=\"',
                                          'img src=\"' + path.toString())
        # Can't use baseUrl=path because external img will not be loaded
        # than :-/
        self.web.setHtml(grep_stdout)
        self.web.settings().setUserStyleSheetUrl(
            QUrl.fromLocalFile(os.getcwd() + os.sep + "/style.css"))
        if y:
            self.web.scroll(0, y)
            self.web.page().mainFrame().scroll(0, y)
            self.web.page().mainFrame().setScrollPosition(QPoint(0, y))
コード例 #24
0
    def _handle_i_edited(self, line, base, fmt, minval, maxval, field):
        msg = None
        text = line.text().replace(' ', '')

        if self._last_val_cache[line] == text:
            return

        try:
            val = int(text, base)
            if val > maxval:
                msg = "Exceeded max value of " + format(maxval, fmt)
            elif val < minval:
                msg = "Under min value of " + format(minval, fmt)
        except ValueError:
            msg = "Invalid format."
        except Exception:
            msg = "Unknown error."

        if msg is None:
            union = ValUnion()
            setattr(union, field, val)
            self._set_new_val(union)
        else:
            line.setStyleSheet("border: 1px solid red")
            line.setToolTip(msg)
            QtGui.QToolTip.showText(line.mapToGlobal(QPoint(0, 0)), msg)
コード例 #25
0
 def __init__(self, parent=None, ast=None):
     ast = ast or ogAST.Decision()
     # Define the point where all branches of the decision can join again
     self.connectionPoint = QPoint(ast.width / 2, ast.height + 30)
     super(Decision, self).__init__(parent,
                                    text=ast.inputString,
                                    x=ast.pos_x,
                                    y=ast.pos_y,
                                    hyperlink=ast.hyperlink)
     self.set_shape(ast.width, ast.height)
     self.setBrush(QColor(255, 255, 202))
     self.minDistanceToSymbolAbove = 0
     self.parser = ogParser
     self.text_alignment = Qt.AlignHCenter
     if ast.comment:
         Comment(parent=self, ast=ast.comment)
コード例 #26
0
ファイル: mayaMixin.py プロジェクト: lovejunjie1/mayaAPI
    def showRepr(self):
        '''Present a string of the parameters used to reproduce the current state of the
        widget used in the show() command.
        
        :Return: str
        '''
        reprDict = {}
        reprDict['dockable'] = self.isDockable()
        reprDict['floating'] = self.isFloating()
        reprDict['area'] = self.dockArea()
        #reprDict['allowedArea'] = ??
        if reprDict['dockable'] == True:
            dockCtrl = self.parent()
            pos = dockCtrl.mapToGlobal(QPoint(0, 0))
        else:
            pos = self.pos()
        sz = self.geometry().size()
        reprDict['x'] = pos.x()
        reprDict['y'] = pos.y()
        reprDict['width'] = sz.width()
        reprDict['height'] = sz.height()

        # Construct the repr show() string
        reprShowList = [
            '%s=%r' % (k, v) for k, v in reprDict.items() if v != None
        ]
        reprShowStr = 'show(%s)' % (', '.join(reprShowList))
        return reprShowStr
コード例 #27
0
    def paintEvent(self, pe):

        if self._drop_zones_shown:
            painter = QPainter(self.viewport(
            ))  # See documentation to know why I draw on the viewport
            painter.setFont(self._titles_font)
            vr = self.rect()

            nb_drop_zones = len(self._drop_zones_titles)

            subr = QRect(vr)
            subr.setHeight(vr.height() / nb_drop_zones)

            for i in range(nb_drop_zones):
                c = self._drop_zones_colors[i]

                text_pen = QPen()
                text_pen.setColor(inverse_colors(c))
                painter.setPen(text_pen)

                if i == self._selected_drop_zone:
                    # mainlog.debug("selected drop zone is {}".format(i))
                    c = c.lighter(200)
                painter.setBrush(c)

                subr.moveTop(int(i * vr.height() / nb_drop_zones))
                painter.drawRect(subr)
                painter.drawText(
                    QPoint(10, int((i + 0.5) * vr.height() / nb_drop_zones)),
                    self._drop_zones_titles[i])
            return None
        else:
            return super(AnimatedTableView, self).paintEvent(pe)
コード例 #28
0
    def _show_completion(self):
        replacement_area, suggestions, quote = find_suggestions(
            self.text(), self.cursorPosition())

        if suggestions:
            # mainlog.debug("Suggestions are ..." + str(suggestions))

            self.replacement_area = replacement_area
            self.quote = quote

            p = self.mapToGlobal(QPoint(self.cursorPos().x(), self.height()))
            self.completion.set_possible_completions(suggestions)
            self.completion.move(p)

            self.completion.activateWindow()  # So that show works
            self.completion.show()
            self.completion.raise_()

            self.completion.items_view.setFocus(Qt.OtherFocusReason)
            self.completion.items_view.setCurrentIndex(
                self.completion.model.index(0, 0))
        else:
            self.replacement_area = None
            self.quote = False
            self.completion.set_possible_completions(None)
            self.completion.hide()

        # self.activateWindow()
        self.setFocus(Qt.OtherFocusReason)

        return suggestions
コード例 #29
0
ファイル: key_widgets.py プロジェクト: thevella/keyplus
 def boundingRect(self):
     if self.angle == 0:
         return QRectF(0, 0, self.w, self.h)
     else:
         sideLen = self.w + self.h
         rect = QRectF(0, 0, 2 * sideLen, 2 * sideLen)
         rect.moveTo(QPoint(-sideLen, -sideLen))
         return rect
コード例 #30
0
ファイル: tasks_widget.py プロジェクト: mousebaiker/WATS
 def getText(self, position):
     """Returns text of a label on given position if such exists, otherwise returns empty string"""
     if helpers.isItemAtPoint(position, self.mainLayout):
         item = helpers.itemAtPoint(position, self.mainLayout)
         if item.widget() != 0:
             position -= QPoint(item.widget().x(), item.widget().y())
             return item.widget().getText(position)
     return ''
コード例 #31
0
    def test_get_dict(self):

        c = Circle(QPoint(10, 10), QPoint(20, 10))

        self.assertEqual(
            c.getDict(), {
                'circle': {
                    'center': {
                        'x': c.center.x(),
                        'y': c.center.y()
                    },
                    'ctrl': {
                        'x': c.ctrl.x(),
                        'y': c.ctrl.y()
                    }
                }
            })
コード例 #32
0
ファイル: painting.py プロジェクト: xkronosua/snippets
 def update_spiral(self):
     # create a polygon providing the corner points of the spiral
     polygon = QPolygon()
     for i in xrange(self.window().width()):
         x = int(math.cos(i * 0.16) * i)
         y = int(math.sin(i * 0.16) * i)
         polygon.append(QPoint(x, y))
     return polygon
コード例 #33
0
ファイル: ant_motion.py プロジェクト: akhtyamovpavel/mr-ant
 def __init__(self):
     self.point = QPoint(0, 0)
     self.step_value = 2  # pixels
     self.last_step_direction = None
     self.last_step_value = None
     self.key_up = Qt.Key_W
     self.key_down = Qt.Key_S
     self.key_left = Qt.Key_A
     self.key_right = Qt.Key_D
コード例 #34
0
ファイル: visualizer.py プロジェクト: liammoyn/DataVisFinal
    def __getStarPair__(self, points, idx):
        """

        :param points: int
        :param idx: int
        :return: QPointF, QPointF
        """
        inner_angle = float(idx) / points * 2 * math.pi
        outer_angle = float(idx) / points * 2 * math.pi + math.pi / points
        inner_x = self.inner_rad * math.cos(inner_angle) + self.center[0]
        inner_y = self.inner_rad * math.sin(inner_angle) + self.center[1]
        outer_x = self.outer_rad * math.cos(outer_angle) + self.center[0]
        outer_y = self.outer_rad * math.sin(outer_angle) + self.center[1]

        inner_point = QPoint(inner_x, inner_y)
        outer_point = QPoint(outer_x, outer_y)

        return inner_point, outer_point
コード例 #35
0
 def _show_built_content(self, thing_to_show):
     if self._last_shown_content is not None:
         self._last_shown_content.hide()
     self._last_shown_content = thing_to_show
     # Always stick it top left to make it easier for the user to know
     # where to put this gui, such that they can see both this one and the
     # built one.
     thing_to_show.move(QPoint(0, 0))
     self._last_shown_content.show()
コード例 #36
0
 def checkBoxRect(self, opt, editor):
     cb_option = QStyleOptionButton()
     style = QApplication.style()
     cb_rect = style.subElementRect(QStyle.SE_CheckBoxIndicator, cb_option,
                                    editor)
     cb_point = QPoint(
         opt.rect.x() + (opt.rect.width() - cb_rect.width()) / 2,
         opt.rect.y() + (opt.rect.height() - cb_rect.height()) / 2)
     return QRect(cb_point, cb_rect.size())
コード例 #37
0
ファイル: ui_resizable.py プロジェクト: mrjackv/polibeepsync
 def getCheckBoxRect(self, option):
     check_box_style_option = QStyleOptionButton()
     check_box_rect = QApplication.style().subElementRect(
         QStyle.SE_CheckBoxIndicator, check_box_style_option, None)
     check_box_point = QPoint(
         option.rect.x() + option.rect.width() / 2 -
         check_box_rect.width() / 2,
         option.rect.y() + option.rect.height() / 2 -
         check_box_rect.height() / 2)
     return QRect(check_box_point, check_box_rect.size())
コード例 #38
0
ファイル: Circle.py プロジェクト: Ingener74/White-Albatross
    def __init__(self, *args, **kwargs):
        self.first_point = FirstPoint()
        self.second_point = SecondPoint()
        self.control = Control()

        Figure.__init__(self, self.first_point)

        self.center = QPoint()
        self.ctrl = QPoint()

        if 'center' in kwargs:
            self.center = kwargs['center']
        if 'ctrl' in kwargs:
            self.ctrl = kwargs['ctrl']
        if 'figure' in kwargs:
            self.center = QPoint(kwargs['figure']['center']['x'],
                                 kwargs['figure']['center']['y'])
            self.ctrl = QPoint(kwargs['figure']['ctrl']['x'],
                               kwargs['figure']['ctrl']['y'])
            self.state = self.control
        if len(args) == 2:
            self.center = args[0]
            self.ctrl = args[1]
        if len(args) == 4:
            self.center = QPoint(args[0], args[1])
            self.ctrl = QPoint(args[2], args[3])
コード例 #39
0
ファイル: sdlSymbols.py プロジェクト: blipvert/opengeode
 def __init__(self, parent=None, ast=None):
     ast = ast or ogAST.Decision()
     # Define the point where all branches of the decision can join again
     self.connectionPoint = QPoint(ast.width / 2, ast.height + 30)
     super(Decision, self).__init__(parent, text=ast.inputString,
             x=ast.pos_x, y=ast.pos_y, hyperlink=ast.hyperlink)
     self.set_shape(ast.width, ast.height)
     self.setBrush(QColor(255, 255, 202))
     self.minDistanceToSymbolAbove = 0
     self.parser = ogParser
     self.text_alignment = Qt.AlignHCenter
     if ast.comment:
         Comment(parent=self, ast=ast.comment)
コード例 #40
0
ファイル: palette_widget.py プロジェクト: DallOner/zoxel
 def mousePressEvent(self, event):
     mouse = QPoint(event.pos())
     if event.buttons() & QtCore.Qt.LeftButton:
         # Click on hues?
         if self._hue_rect.contains(mouse.x(), mouse.y()):
             y = mouse.y()
             c = QtGui.QColor.fromHsvF(float(y) / self.height(), self._saturation, self._value)
             self.color = c
         # Click on colors?
         elif self._shades_rect.contains(mouse.x(), mouse.y()):
             # calculate saturation and value
             x = mouse.x()
             y = mouse.y()
             c = QtGui.QColor.fromHsvF(self._hue, 1 - float(y) / self._shades_rect.height(),
                                       float(x) / self._shades_rect.width())
             self.color = c
コード例 #41
0
    def __decompose(self, poly):
        lower_poly = []
        upper_poly = []

        upper_int = QPoint(0, 0)
        lower_int = QPoint(0, 0)

        upper_index = 0
        lower_index = 0
        closest_index = 0

        p = QPoint(0, 0)

        for pi in poly:
            if is_reflex(poly, pi):

                pim1 = poly[-1 if pi is poly[0] else poly.index(pi) - 1]
                pip1 = poly[0 if pi is poly[-1] else poly.index(pi) + 1]

                self.reflex_vertices.append(pi)
                upper_dist = sys.maxint
                lower_dist = sys.maxint

                for pj in poly:
                    pjm1 = poly[-1 if pj is poly[0] else poly.index(pj) - 1]
                    pjp1 = poly[0 if pj is poly[-1] else poly.index(pj) + 1]

                    if left(pim1, pi, pj) and right_on(pim1, pi, pjm1):
                        p = intersection(pim1, pi, pj, pjm1)
                        if right(pip1, pi, p):
                            d = sqdist(pi, p)
                            if d < lower_dist:
                                lower_dist = d
                                lower_int = p
                                lower_index = poly.index(pj)

                    if left(pip1, pi, pjp1) and right_on(pip1, pi, pj):
                        p = intersection(pip1, pi, pj, pjp1)
                        if left(pim1, pi, p):
                            d = sqdist(pi, p)
                            if d < upper_dist:
                                upper_dist = d
                                upper_int = p
                                upper_index = poly.index(pj)

                i = poly.index(pi)
                if lower_index == ((upper_index + 1) % len(poly)):
                    p.setX((lower_int.x() + upper_int.x()) / 2)
                    p.setY((lower_int.y() + upper_int.y()) / 2)

                    self.steiner_points.append(p)

                    if i < upper_index:
                        lower_poly += poly[i : upper_index + 1]

                        lower_poly.append(p)
                        upper_poly.append(p)
                        if lower_index != 0:
                            upper_poly += poly[lower_index:]

                        upper_poly += poly[: i + 1]
                    else:
                        if i != 0:
                            lower_poly += poly[i:]

                        lower_poly += poly[: upper_index + 1]
                        lower_poly.append(p)
                        upper_poly.append(p)

                        upper_poly += poly[lower_index : i + 1]
                else:
                    if lower_index > upper_index:
                        upper_index += len(poly)

                    closest_dist = sys.float_info.max
                    for j in xrange(lower_index, upper_index + 1):

                        pj = poly[j % len(poly)]

                        if left_on(pim1, pi, pj) and right_on(pip1, pi, pj):
                            d = sqdist(pi, pj)
                            if d < closest_dist:
                                closest_dist = d
                                closest_index = j % len(poly)

                    if i < closest_index:
                        lower_poly += poly[i : closest_index + 1]
                        if closest_index != 0:
                            upper_poly += poly[closest_index:]

                        upper_poly += poly[: i + 1]
                    else:
                        if i != 0:
                            lower_poly += poly[i:]

                        lower_poly += poly[: closest_index + 1]
                        upper_poly += poly[closest_index : i + 1]

                if len(lower_poly) < len(upper_poly):
                    self.decompose(lower_poly)
                    self.decompose(upper_poly)
                else:
                    self.decompose(upper_poly)
                    self.decompose(lower_poly)
                return

        self.polys.append(poly)
コード例 #42
0
class Rectangle(Figure):
    def __init__(self, *args, **kwargs):

        self.first_point = FirstPoint()
        self.second_point = SecondPoint()
        self.control = Control()

        self.p1 = QPoint()
        self.p2 = QPoint()

        Figure.__init__(self, self.first_point)
        if 'x1' in kwargs and 'y1' in kwargs:
            self.p1 = QPoint(kwargs['x1'], kwargs['y1'])
        if 'x2' in kwargs and 'y2' in kwargs:
            self.p2 = QPoint(kwargs['x2'], kwargs['y2'])
        if 'p1' in kwargs:
            self.p1 = kwargs['p1']
        if 'p2' in kwargs:
            self.p2 = kwargs['p2']
        if len(args) == 2:
            self.p1 = args[0]
            self.p2 = args[1]
        if len(args) == 4:
            self.p1 = QPoint(args[0], args[1])
            self.p2 = QPoint(args[2], args[3])

        if 'figure' in kwargs:
            self.p1 = QPoint(kwargs['figure']['x1'], kwargs['figure']['y1'])
            self.p2 = QPoint(kwargs['figure']['x2'], kwargs['figure']['y2'])
            self.state = self.control

    def draw(self, painter, scale):
        painter.save()
        if not self.p1.isNull() and not self.p2.isNull():
            painter.setPen(QPen(QBrush(QColor(232, 109, 21) if self.state is not self.control else
                                       QColor(21, 144, 232)),
                                self.lineWidth(scale),
                                Qt.SolidLine))
            painter.setBrush(QBrush(QColor(21, 144, 232, 150)))
            painter.drawRect(QRect(self.p1, self.p2))

            self.drawControlPoint(painter, self.p1, QColor(31, 174, 222), scale)
            self.drawControlPoint(painter, self.p2, QColor(222, 79, 31), scale)

        Figure.draw(self, painter, scale)
        painter.restore()

    def getDict(self):
        return {
            'rect': {
                'x1': self.p1.x(),
                'y1': self.p1.y(),
                'x2': self.p2.x(),
                'y2': self.p2.y()
            }
        }

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return 'Rectangle(({x1}, {y1}), ({x2}, {y2}))'.format(x1=self.p1.x(),
                                                              y1=self.p1.y(),
                                                              x2=self.p2.x(),
                                                              y2=self.p2.y())
コード例 #43
0
ファイル: sdlSymbols.py プロジェクト: Kampbell/opengeode
class Decision(VerticalSymbol):
    ''' SDL DECISION Symbol '''
    _unique_followers = ['Comment']
    _insertable_followers = ['DecisionAnswer', 'Task', 'ProcedureCall',
                             'Output', 'Decision', 'Label']
    _terminal_followers = ['Join', 'State', 'ProcedureStop']
    common_name = 'decision'
    # Define reserved keywords for the syntax highlighter
    blackbold = SDL_BLACKBOLD + ['\\b{}\\b'.format(word)
                                   for word in ('AND', 'OR')]
    redbold = SDL_REDBOLD

    def __init__(self, parent=None, ast=None):
        ast = ast or ogAST.Decision()
        self.ast = ast
        # Define the point where all branches of the decision can join again
        self.connectionPoint = QPoint(ast.width / 2, ast.height + 30)
        super(Decision, self).__init__(parent, text=ast.inputString,
                x=ast.pos_x or 0, y=ast.pos_y or 0, hyperlink=ast.hyperlink)
        self.set_shape(ast.width, ast.height)
        self.setBrush(QColor(255, 255, 202))
        self.minDistanceToSymbolAbove = 0
        self.parser = ogParser
        self.text_alignment = Qt.AlignHCenter
        if ast.comment:
            Comment(parent=self, ast=ast.comment)

    @property
    def terminal_symbol(self):
        '''
            Compute dynamically if the item is terminal by checking
            if all its branches end with a terminator
        '''
        for branch in self.branches():
            if not branch.last_branch_item.terminal_symbol:
                return False
        return True

    @property
    def completion_list(self):
        ''' Set auto-completion list '''
        return chain(variables_autocompletion(self), ('length', 'present'))

    def branches(self):
        ''' Return the list of decision answers (as a generator) '''
        return (branch for branch in self.childSymbols()
                if isinstance(branch, DecisionAnswer))

    def set_shape(self, width, height):
        ''' Define polygon points to draw the symbol '''
        path = QPainterPath()
        path.moveTo(width / 2, 0)
        path.lineTo(width, height / 2)
        path.lineTo(width / 2, height)
        path.lineTo(0, height / 2)
        path.lineTo(width / 2, 0)
        self.setPath(path)
        super(Decision, self).set_shape(width, height)

    def resize_item(self, rect):
        ''' On resize event, make sure connection points are updated '''
        delta_y = self.boundingRect().height() - rect.height()
        super(Decision, self).resize_item(rect)
        self.connectionPoint.setX(self.boundingRect().center().x())
        self.connectionPoint.setY(self.connectionPoint.y() - delta_y)
        self.update_connections()

    def update_connections(self):
        ''' Redefined - update arrows shape below connection point '''
        super(Decision, self).update_connections()
        for branch in self.branches():
            for cnx in branch.last_branch_item.connections():
                cnx.reshape()

    def updateConnectionPointPosition(self):
        ''' Compute the joining point of decision branches '''
        new_y = 0
        new_x = self.boundingRect().width() / 2.0
        answers = False
        for branch in self.branches():
            answers = True
            last_cnx = None
            last = branch.last_branch_item
            try:
                # To compute the branch length, we must keep only the symbols,
                # so we must remove the last connection (if any)
                last_cnx, = (c for c in last.childItems() if
                    isinstance(c, Connection) and not
                    isinstance(c.child, (Comment, HorizontalSymbol)))
                # Don't set parent item to None to avoid Qt segfault
                last_cnx.setParentItem(self)
            except ValueError:
                pass
            branch_len = branch.y() + (
                    branch.boundingRect() |
                    branch.childrenBoundingRect()).height()
            try:
                last_cnx.setParentItem(last)
            except AttributeError:
                pass
            # If last item was a decision, use its connection point
            # position to get the length of the branch:
            try:
                branch_len = (last.connectionPoint.y() +
                        self.mapFromScene(0, last.scenePos().y()).y())
            except AttributeError:
                pass
            # Rounded with int() -> mandatory when view scale has changed
            new_y = int(max(new_y, branch_len))
        if not answers:
            new_y = int(self.boundingRect().height())
        new_y += 15
        delta = new_y - self.connectionPoint.y()
        self.connectionPoint.setY(new_y)
        self.connectionPoint.setX(new_x)
        if delta != 0:
            child = self.next_aligned_symbol()
            try:
                child.pos_y += delta
            except AttributeError:
                pass
        self.update_connections()
コード例 #44
0
ファイル: samplerender.py プロジェクト: penma/dicraft
	def __init__(self, parent=None):
		super(GLWidget, self).__init__(parent)

		self.xRot = 0
		self.yRot = 0
		self.lastPos = QPoint()
コード例 #45
0
ファイル: samplerender.py プロジェクト: penma/dicraft
class GLWidget(QGLWidget):
	def __init__(self, parent=None):
		super(GLWidget, self).__init__(parent)

		self.xRot = 0
		self.yRot = 0
		self.lastPos = QPoint()

	def minimumSizeHint(self):
		return QSize(50, 50)

	def sizeHint(self):
		return QSize(400, 400)

	def setXRotation(self, angle):
		angle = self.normalizeAngle(angle)
		if angle != self.xRot:
			self.xRot = angle
			self.updateGL()

	def setYRotation(self, angle):
		angle = self.normalizeAngle(angle)
		if angle != self.yRot:
			self.yRot = angle
			self.updateGL()

	def initializeGL(self):
		# gl one-time init code
		pass

	def paintGL(self):
		# do ALL the rendering (clear etc)
		pass

	def resizeGL(self, width, height):
		side = min(width, height)
		if side < 0:
			return

		GL.glViewport((width - side) // 2, (height - side) // 2, side, side)
		# TODO make the changed perspective known to libdicraft-render

	def mousePressEvent(self, event):
		self.lastPos = event.pos()

	def mouseMoveEvent(self, event):
		dx = event.x() - self.lastPos.x()
		dy = event.y() - self.lastPos.y()

		if event.buttons() & Qt.LeftButton:
			self.setXRotation(self.xRot + 8 * dy)
			self.setYRotation(self.yRot + 8 * dx)

		self.lastPos = event.pos()

	def normalizeAngle(self, angle):
		while angle < 0:
			angle += 360 * 16
		while angle > 360 * 16:
			angle -= 360 * 16
		return angle
コード例 #46
0
ファイル: Circle.py プロジェクト: Ingener74/White-Albatross
class Circle(Figure):
    def __init__(self, *args, **kwargs):
        self.first_point = FirstPoint()
        self.second_point = SecondPoint()
        self.control = Control()

        Figure.__init__(self, self.first_point)

        self.center = QPoint()
        self.ctrl = QPoint()

        if 'center' in kwargs:
            self.center = kwargs['center']
        if 'ctrl' in kwargs:
            self.ctrl = kwargs['ctrl']
        if 'figure' in kwargs:
            self.center = QPoint(kwargs['figure']['center']['x'],
                                 kwargs['figure']['center']['y'])
            self.ctrl = QPoint(kwargs['figure']['ctrl']['x'],
                               kwargs['figure']['ctrl']['y'])
            self.state = self.control
        if len(args) == 2:
            self.center = args[0]
            self.ctrl = args[1]
        if len(args) == 4:
            self.center = QPoint(args[0], args[1])
            self.ctrl = QPoint(args[2], args[3])

    def draw(self, painter, scale):
        painter.save()
        if not self.center.isNull() and not self.ctrl.isNull():
            radius = distance(self.center, self.ctrl)
            painter.setPen(QPen(QBrush(QColor(232, 109, 21) if self.state is not self.control else
                                       QColor(21, 144, 232)),
                                self.lineWidth(scale),
                                Qt.SolidLine))
            painter.setBrush(QBrush(QColor(21, 144, 232, 150)))
            painter.drawEllipse(self.center, radius, radius)

            self.drawControlPoint(painter, self.center, QColor(31, 174, 222), scale)
            self.drawControlPoint(painter, self.ctrl, QColor(222, 79, 31), scale)

        Figure.draw(self, painter, scale)
        painter.restore()

    def getDict(self):
        return {
            'circle': {
                'center': {
                    'x': self.center.x(),
                    'y': self.center.y(),
                },
                'ctrl': {
                    'x': self.ctrl.x(),
                    'y': self.ctrl.y(),
                }
            }
        }

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return 'Circle(({x}, {y}), {radius})'.format(x=self.center.x(),
                                                     y=self.center.y(),
                                                     radius=distance(self.center, self.ctrl))
コード例 #47
0
ファイル: ant_motion.py プロジェクト: akhtyamovpavel/mr-ant
class AntMotion():
    def __init__(self):
        self.point = QPoint(0, 0)
        self.step_value = 2  # pixels
        self.last_step_direction = None
        self.last_step_value = None
        self.key_up = Qt.Key_W
        self.key_down = Qt.Key_S
        self.key_left = Qt.Key_A
        self.key_right = Qt.Key_D

    def _move(self, doStep, coordinate, direction, *args):
        if len(args) == 1:
            step_value = args[0]
        else:
            step_value = self.step_value

        if direction == 'up' or direction == 'left':
            doStep(coordinate - step_value)
        else:
            doStep(coordinate + step_value)

        self.last_step_direction = direction
        self.last_step_value = step_value

    def up(self, *args):
        self._move(self.point.setY, self.point.y(), 'up', *args)

    def down(self, *args):
        self._move(self.point.setY, self.point.y(), 'down', *args)

    def left(self, *args):
        self._move(self.point.setX, self.point.x(), 'left', *args)

    def right(self, *args):
        self._move(self.point.setX, self.point.x(), 'right', *args)

    def reinitLastStepDirection(self):
        self.last_step_direction = None

    def cancelLastStep(self):
        if 'up' == self.last_step_direction:
            self.down(self.last_step_value)
        elif 'down' == self.last_step_direction:
            self.up(self.last_step_value)
        elif 'left' == self.last_step_direction:
            self.right(self.last_step_value)
        elif 'right' == self.last_step_direction:
            self.left(self.last_step_value)

        self.reinitLastStepDirection()

    def setStep(self, newStep):
        self.step = newStep

    def setKeyUp(self, key):
        self.key_up = key

    def setKeyDown(self, key):
        self.key_down = key

    def setKeyLeft(self, key):
        self.key_left = key

    def setKeyRight(self, key):
        self.key_right = key
コード例 #48
0
ファイル: sdlSymbols.py プロジェクト: meyerlaurent/opengeode
class Decision(VerticalSymbol):
    ''' SDL DECISION Symbol '''
    _unique_followers = ['Comment']
    _insertable_followers = ['DecisionAnswer', 'Task', 'ProcedureCall',
                             'Output', 'Decision', 'Label']
    _terminal_followers = ['Join', 'State', 'ProcedureStop']
    common_name = 'decision'
    # Define reserved keywords for the syntax highlighter
    blackbold = SDL_BLACKBOLD + ['\\b{}\\b'.format(word)
                                   for word in ('AND', 'OR')]
    redbold = SDL_REDBOLD
    completion_list = {'length', 'present'}

    def __init__(self, parent=None, ast=None):
        ast = ast or ogAST.Decision()
        # Define the point where all branches of the decision can join again
        self.connectionPoint = QPoint(ast.width / 2, ast.height + 30)
        super(Decision, self).__init__(parent, text=ast.inputString,
                x=ast.pos_x, y=ast.pos_y, hyperlink=ast.hyperlink)
        self.set_shape(ast.width, ast.height)
        self.setBrush(QColor(255, 255, 202))
        self.minDistanceToSymbolAbove = 0
        self.parser = ogParser
        self.text_alignment = Qt.AlignHCenter
        if ast.comment:
            Comment(parent=self, ast=ast.comment)

    @property
    def terminal_symbol(self):
        '''
            Compute dynamically if the item is terminal by checking
            if all its branches end with a terminator
        '''
        for branch in self.branches():
            if not branch.last_branch_item.terminal_symbol:
                return False
        return True

    def branches(self):
        ''' Return the list of decision answers (as a generator) '''
        return (branch for branch in self.childSymbols()
                if isinstance(branch, DecisionAnswer))

    def check_syntax(self):
        ''' Redefined function, to check only the symbol, not recursively '''
        _, syntax_errors, _, _, _ = self.parser.parseSingleElement(
                self.common_name, self.PR(recursive=False))
        try:
            # LOG.error('\n'.join(syntax_errors))
            self.scene().raise_syntax_errors(syntax_errors)
        except AttributeError:
            LOG.debug('raise_syntax_error raised an exception')

    def set_shape(self, width, height):
        ''' Define polygon points to draw the symbol '''
        path = QPainterPath()
        path.moveTo(width / 2, 0)
        path.lineTo(width, height / 2)
        path.lineTo(width / 2, height)
        path.lineTo(0, height / 2)
        path.lineTo(width / 2, 0)
        self.setPath(path)
        super(Decision, self).set_shape(width, height)

    def resize_item(self, rect):
        ''' On resize event, make sure connection points are updated '''
        delta_y = self.boundingRect().height() - rect.height()
        super(Decision, self).resize_item(rect)
        self.connectionPoint.setX(self.boundingRect().center().x())
        self.connectionPoint.setY(self.connectionPoint.y() - delta_y)
        self.update_connections()

    def update_connections(self):
        ''' Redefined - update arrows shape below connection point '''
        super(Decision, self).update_connections()
        for branch in self.branches():
            for cnx in branch.last_branch_item.connections():
                cnx.reshape()

    def updateConnectionPointPosition(self):
        ''' Compute the joining point of decision branches '''
        new_y = 0
        new_x = self.boundingRect().width() / 2.0
        answers = False
        for branch in self.branches():
            answers = True
            last_cnx = None
            last = branch.last_branch_item
            try:
                # To compute the branch length, we must keep only the symbols,
                # so we must remove the last connection (if any)
                last_cnx, = (c for c in last.childItems() if
                    isinstance(c, Connection) and not
                    isinstance(c.child, (Comment, HorizontalSymbol)))
                # Don't set parent item to None to avoid Qt segfault
                last_cnx.setParentItem(self)
            except ValueError:
                pass
            branch_len = branch.y() + (
                    branch.boundingRect() |
                    branch.childrenBoundingRect()).height()
            try:
                last_cnx.setParentItem(last)
            except AttributeError:
                pass
            # If last item was a decision, use its connection point
            # position to get the length of the branch:
            try:
                branch_len = (last.connectionPoint.y() +
                        self.mapFromScene(0, last.scenePos().y()).y())
            except AttributeError:
                pass
            # Rounded with int() -> mandatory when view scale has changed
            new_y = int(max(new_y, branch_len))
        if not answers:
            new_y = int(self.boundingRect().height())
        new_y += 15
        delta = new_y - self.connectionPoint.y()
        self.connectionPoint.setY(new_y)
        self.connectionPoint.setX(new_x)
        if delta != 0:
            child = self.next_aligned_symbol()
            try:
                child.moveBy(0, delta)
            except AttributeError:
                pass
        self.update_connections()

    def PR(self, recursive=True):
        ''' Get PR notation of a decision (possibly recursively) '''
        comment = self.comment.PR() if self.comment else u';'
        pos = self.scenePos()
        result = [u'/* CIF DECISION ({x}, {y}), ({w}, {h}) */\n'
                '{hlink}'
                'DECISION {d}{comment}'.format(
                    hlink=self.text.PR(), d=unicode(self),
                    x=int(pos.x()), y=int(pos.y()),
                    w=int(self.boundingRect().width()),
                    h=int(self.boundingRect().height()), comment=comment)]
        if recursive:
            for answer in self.branches():
                if unicode(answer).lower().strip() == 'else':
                    result.append(answer.PR())
                else:
                    result.insert(1, answer.PR())
        result.append('ENDDECISION;')
        return u'\n'.join(result)
コード例 #49
0
ファイル: bug_606.py プロジェクト: Hasimir/PySide
 def testQPointToTuple(self):
     p = QPoint(1, 2)
     self.assertEqual((1, 2), p.toTuple())