예제 #1
0
파일: _ohlc.py 프로젝트: pikers/piker
    def paint(
        self,
        p: QtGui.QPainter,
        opt: QtWidgets.QStyleOptionGraphicsItem,
        w: QtWidgets.QWidget

    ) -> None:

        if self._in_ds:
            return

        profiler = pg.debug.Profiler(
            disabled=not pg_profile_enabled(),
            gt=ms_slower_then,
        )

        # p.setCompositionMode(0)

        # TODO: one thing we could try here is pictures being drawn of
        # a fixed count of bars such that based on the viewbox indices we
        # only draw the "rounded up" number of "pictures worth" of bars
        # as is necesarry for what's in "view". Not sure if this will
        # lead to any perf gains other then when zoomed in to less bars
        # in view.
        p.setPen(self.last_bar_pen)
        p.drawLines(*tuple(filter(bool, self._last_bar_lines)))
        profiler('draw last bar')

        p.setPen(self.bars_pen)
        p.drawPath(self.path)
        profiler(f'draw history path: {self.path.capacity()}')
예제 #2
0
    def paintEvent(self, event):
        """Paint event for the overlay

        :param event:   QPaintEvent event
        :type event:    QPaintEvent
        """
        super().paintEvent(event)
        painter = QPainter(self)
        pen = QPen(Qt.black)
        pen.setWidth(1)
        painter.setPen(pen)
        painter.setBrush(Qt.NoBrush)
        painter.drawRect(0, 0, 16 * 25 - 1, self.height * 25 - 1)
        lines = []
        for longitude in range(16):
            line = QLineF(longitude * 25, 0, longitude * 25, self.height * 25)
            lines.append(line)
        for latitude in range(self.height):
            line = QLineF(0, latitude * 25, 16 * 25, latitude * 25)
            lines.append(line)
        painter.drawLines(lines)
        s_root, s_width, s_height = self.selected
        x = s_root % 16
        y = math.floor(s_root / 16)
        pen.setColor(Qt.red)
        pen.setWidth(3)
        pen.setJoinStyle(Qt.MiterJoin)
        painter.setPen(pen)
        painter.drawRect(x * 25, y * 25, s_width * 25, s_height * 25)
예제 #3
0
파일: GScene.py 프로젝트: Mr-WangJin/dms
 def drawBackground(self, painter: QPainter, rect: QRectF):
     rect = self.sceneRect()
     super().drawBackground(painter, rect)
     # 绘制纯色背景
     # 绘制网格
     xLines_thin = []
     yLines_thin = []
     xLines_blod = []
     yLines_blod = []
     for i in range(0, self.rectSize, self.gridSize):
         if (i % 100) != 0:
             xLines_thin.append(
                 QLineF(rect.left(),
                        rect.top() + i, rect.right(),
                        rect.top() + i))
             yLines_thin.append(
                 QLineF(rect.left() + i, rect.top(),
                        rect.left() + i, rect.bottom()))
         else:
             xLines_blod.append(
                 QLineF(rect.left(),
                        rect.top() + i, rect.right(),
                        rect.top() + i))
             yLines_blod.append(
                 QLineF(rect.left() + i, rect.top(),
                        rect.left() + i, rect.bottom()))
     painter.setPen(QPen(self.grid_line_color, self.tinny_grid_line_width))
     painter.drawLines(xLines_thin)
     painter.drawLines(yLines_thin)
     painter.setPen(QPen(self.grid_line_color, self.bold_grid_line_width))
     painter.drawLines(xLines_blod)
     painter.drawLines(yLines_blod)
    def paintEvent(self, a0: QPaintEvent):
        # print("paint")
        painter = QPainter(self)

        # painter.begin(self)
        painter.drawPixmap(0, 0, self.width(), self.height(), self.qpix)
        if self.enable_extra_14_bytes and self.extra_data:
            pix_width = self.width() / self.imgWidth
            pix_height = self.height() / self.imgHeight
            # painter.setPen(QPen(Qt.red, -14))
            painter.setBrush(QBrush(Qt.red))
            painter.drawEllipse(self.extra_data[1] * pix_width,
                                self.extra_data[0] * pix_height, pix_width,
                                pix_height)
            painter.drawEllipse(self.extra_data[2] * pix_width,
                                self.extra_data[0] * pix_height, pix_width,
                                pix_height)
            painter.drawEllipse(self.extra_data[3] * pix_width,
                                self.extra_data[0] * pix_height, pix_width,
                                pix_height)
            painter.drawEllipse(self.extra_data[4] * pix_width,
                                self.extra_data[0] * pix_height, pix_width,
                                pix_height)

        if self.enable_grid:
            painter.setPen(Qt.darkBlue)
            painter.drawLines(self.grid_points)
예제 #5
0
    def draw_background(self, painter: QtGui.QPainter, rect: QtCore.QRectF) -> None:
        if not self._show_grid:
            return

        painter.setPen(
            QtGui.QPen(
                QtGui.QColor(0, 0, 0)
            )
        )

        lines = []

        for x in list(self.stacker_map.row_termination_points())[:-1]:
            if rect.left() <= x <= rect.right():
                lines.append(
                    QLineF(
                        x, rect.top(), x, rect.bottom(),
                    )
                )

        for y in list(self.stacker_map.column_termination_points())[:-1]:
            if rect.top() <= y <= rect.bottom():
                lines.append(
                    QLineF(
                        rect.left(), y, rect.right(), y,
                    )
                )

        painter.drawLines(lines)
예제 #6
0
    def drawBackground(self, painter: QPainter, rect: QRectF):

        # freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
        if self.draw_grid and len(self.frequencies) > 0:
            painter.setPen(QPen(painter.pen().color(), 0))
            parent_width = self.parent().width() if hasattr(
                self.parent(), "width") else 750
            view_rect = self.parent().view_rect() if hasattr(
                self.parent(), "view_rect") else rect

            font_width = self.font_metrics.width(
                Formatter.big_value_with_suffix(self.center_freq) + "   ")
            x_grid_size = int(view_rect.width() / parent_width * font_width)
            # x_grid_size = int(0.1 * view_rect.width()) if 0.1 * view_rect.width() > 1 else 1
            y_grid_size = 1
            x_mid = np.where(self.frequencies == 0)[0]
            x_mid = int(x_mid[0]) if len(x_mid) > 0 else 0

            left = int(rect.left()) - (int(rect.left()) % x_grid_size)
            left = left if left > 0 else 0

            top = rect.top() - (rect.top() % y_grid_size)
            bottom = rect.bottom() - (rect.bottom() % y_grid_size)
            right_border = int(
                rect.right()) if rect.right() < len(self.frequencies) else len(
                    self.frequencies)

            x_range = list(range(x_mid, left, -x_grid_size)) + list(
                range(x_mid, right_border, x_grid_size))
            lines = [QLineF(x, rect.top(), x, bottom) for x in x_range] \
                    + [QLineF(rect.left(), y, rect.right(), y) for y in np.arange(top, bottom, y_grid_size)]

            painter.drawLines(lines)
            scale_x, scale_y = util.calc_x_y_scale(rect, self.parent())

            painter.scale(scale_x, scale_y)
            counter = -1  # Counter for Label for every second line

            for x in x_range:
                freq = self.frequencies[x]
                counter += 1

                if freq != 0 and (counter % 2 !=
                                  0):  # Label for every second line
                    continue

                if freq != 0:
                    prefix = "+" if freq > 0 else ""
                    value = prefix + Formatter.big_value_with_suffix(freq, 2)
                else:
                    counter = 0
                    value = Formatter.big_value_with_suffix(6800e6 -
                                                            self.center_freq +
                                                            self.status_k)
                font_width = self.font_metrics.width(value)
                painter.drawText(x / scale_x - font_width / 2,
                                 bottom / scale_y, value)
예제 #7
0
 def paintEvent(self, event):
     lin = [QLineF(400, 150, 770, 150)]
     QWidget.paintEvent(self, event)
     painter = QPainter(self)
     painter.setPen(QPen(Qt.darkYellow, 6))
     painter.drawLines(ln for ln in lin)
     painter.setPen(QPen(Qt.lightGray, 6))
     painter.drawLines(el for el in self.lines)
     if not self.center.isNull():
         painter.drawEllipse(self.center, self.rad, self.rad)
예제 #8
0
 def drawCross(self):
     w, h = self._getDimensions()
     painter = QPainter(self)
     self.pen.setColor(QColor.fromRgb(47, 101, 236))
     painter.setPen(self.pen)
     lines = [QLineF(self.delta, self.delta,
                     w - self.delta, h - self.delta),
              QLineF(self.delta, h - self.delta,
                     w - self.delta, self.delta)]
     painter.drawLines(lines)
예제 #9
0
파일: CursorControl.py 프로젝트: oh3eqn/D43
 def drawCursors(self):        
     qp = QPainter()
     qp.begin(self)
     for cursor in self.cursors:               
         pen = QPen(cursor.getColor(), 1, Qt.SolidLine)
         qp.setPen(pen)
         line = self.getLine(cursor)
         qp.drawLine(line)
         if cursor.getStyle() == CursorStyle.barred:
             lines = self.getBars(cursor)
             pen = QPen(cursor.getBarColor(), 1, Qt.SolidLine)
             qp.setPen(pen)
             qp.drawLines(lines)
     qp.end()
예제 #10
0
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawImage(event.rect(), self.image.scaledToWidth(self.width*self.image_pixel_width, Qt.SmoothTransformation))

        if self.agc_roi_from != None and self.agc_roi_to != None and not self.image_is_16bit:
            pen = QPen()
            pen.setColor(Qt.green)
            pen.setWidth(1)
            painter.setPen(pen)

            roi = self.parent.get_agc_roi()
            painter.drawRect(roi[0] * self.image_pixel_width + 1,
                             roi[1] * self.image_pixel_width + 1,
                             (roi[2] - roi[0]) * self.image_pixel_width + 1,
                             (roi[3] - roi[1]) * self.image_pixel_width + 1)

            self.parent.update_agc_roi_label()

        if self.spotmeter_roi_from != None and self.spotmeter_roi_to != None:
            pen = QPen()
            pen.setColor(Qt.white)
            pen.setWidth(1)
            painter.setPen(pen)

            from_x, from_y, to_x, to_y = self.parent.get_spotmeter_roi()

            from_x = from_x * self.image_pixel_width + 1
            from_y = from_y * self.image_pixel_width + 1
            to_x = to_x * self.image_pixel_width + 1
            to_y = to_y * self.image_pixel_width + 1

            cross_x = from_x + (to_x-from_x) / 2.0
            cross_y = from_y + (to_y-from_y) / 2.0

            if to_x-from_x > 5 or to_y - from_y > 5:
                lines = [QLineF(from_x, from_y, from_x + self.crosshair_width, from_y),
                         QLineF(from_x, from_y, from_x, from_y + self.crosshair_width),
                         QLineF(to_x, to_y, to_x, to_y - self.crosshair_width),
                         QLineF(to_x, to_y, to_x - self.crosshair_width, to_y),
                         QLineF(from_x, to_y, from_x, to_y-self.crosshair_width),
                         QLineF(from_x, to_y, from_x + self.crosshair_width, to_y),
                         QLineF(to_x, from_y, to_x, from_y+self.crosshair_width),
                         QLineF(to_x, from_y, to_x - self.crosshair_width, from_y)]
                painter.drawLines(lines)

            lines = [QLineF(cross_x - self.crosshair_width, cross_y, cross_x + self.crosshair_width, cross_y),
                     QLineF(cross_x, cross_y - self.crosshair_width, cross_x, cross_y+self.crosshair_width)]
            painter.drawLines(lines)

            self.parent.update_spotmeter_roi_label()
예제 #11
0
    def drawBackground(self, painter: QPainter, rect: QRectF):
        # freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
        if self.draw_grid and len(self.frequencies) > 0:
            painter.setPen(QPen(painter.pen().color(), Qt.FlatCap))
            parent_width = self.parent().width() if hasattr(self.parent(), "width") else 750
            view_rect = self.parent().view_rect() if hasattr(self.parent(), "view_rect") else rect

            font_width = self.font_metrics.width(Formatter.big_value_with_suffix(self.center_freq) + "   ")
            x_grid_size = int(view_rect.width() / parent_width * font_width)
            # x_grid_size = int(0.1 * view_rect.width()) if 0.1 * view_rect.width() > 1 else 1
            y_grid_size = view_rect.height() / parent_width * font_width
            x_mid = np.where(self.frequencies == 0)[0]
            x_mid = int(x_mid[0]) if len(x_mid) > 0 else 0

            left = int(rect.left()) - (int(rect.left()) % x_grid_size)
            left = left if left > 0 else 0

            top = rect.top() - (rect.top() % y_grid_size)
            bottom = rect.bottom() - (rect.bottom() % y_grid_size)
            right_border = int(rect.right()) if rect.right() < len(self.frequencies) else len(self.frequencies)

            x_range = list(range(x_mid, left, -x_grid_size)) + list(range(x_mid, right_border, x_grid_size))
            lines = [QLineF(x, rect.top(), x, bottom) for x in x_range] \
                    + [QLineF(rect.left(), y, rect.right(), y) for y in np.arange(top, bottom, y_grid_size)]

            painter.drawLines(lines)
            scale_x = view_rect.width() / parent_width
            scale_y = view_rect.height() / parent_width
            painter.scale(scale_x, scale_y)

            font_height = self.font_metrics.height()
            counter = -1  # Counter for Label for every second line

            for x in x_range:
                freq =  self.frequencies[x]
                counter += 1

                if freq != 0 and (counter % 2 != 0): # Label for every second line
                    continue

                if freq != 0:
                    prefix = "+" if freq > 0 else ""
                    value = prefix+Formatter.big_value_with_suffix(freq, 2)
                else:
                    counter = 0
                    value = Formatter.big_value_with_suffix(self.center_freq)
                font_width = self.font_metrics.width(value)
                painter.drawText(x / scale_x - font_width / 2,
                                 bottom / scale_y + font_height, value)
예제 #12
0
 def paintEvent(self, event):
     super(ScaleWindow, self).paintEvent(event)
     if self._image:
         painter = QPainter(self)
         painter.setRenderHint(QPainter.Antialiasing, True)
         path = QPainterPath()
         radius = min(self.width(), self.height()) / 2
         path.addRoundedRect(QRectF(self.rect()), radius, radius)
         painter.setClipPath(path)
         painter.drawImage(self.rect(), self._image)
         painter.setPen(QPen(QColor(0, 174, 255), 3))
         hw = self.width() / 2
         hh = self.height() / 2
         painter.drawLines(QLineF(hw, 0, hw, self.height()), QLineF(0, hh, self.width(), hh))
         painter.setPen(QPen(Qt.white, 3))
         painter.drawRoundedRect(self.rect(), radius, radius)
예제 #13
0
    def drawBackground(self, painter: QtGui.QPainter, rect: QtCore.QRectF):
        grid_size = 25

        left = int(rect.left()) - (int(rect.left()) % grid_size)
        top = int(rect.top()) - (int(rect.top()) % grid_size)

        lines = []

        for x in range(left, int(rect.right()), grid_size):
            lines.append(QLineF(x, rect.top(), x, rect.bottom()))

        for y in range(top, int(rect.bottom()), grid_size):
            lines.append(QLineF(rect.left(), y, rect.right(), y))

        # print(len(lines))

        painter.drawLines(lines)
예제 #14
0
    def drawBackground(self, painter: QPainter, rect: QRectF):
        # freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
        if self.draw_grid and len(self.frequencies) > 0:
            painter.setPen(QPen(painter.pen().color(), Qt.FlatCap))
            parent_width = self.parent().width() if hasattr(
                self.parent(), "width") else 750
            view_rect = self.parent().view_rect() if hasattr(
                self.parent(), "view_rect") else rect

            font_width = self.font_metrics.width(
                self.value_with_suffix(self.center_freq) + "   ")
            x_grid_size = int(view_rect.width() / parent_width * font_width)
            # x_grid_size = int(0.1 * view_rect.width()) if 0.1 * view_rect.width() > 1 else 1
            y_grid_size = view_rect.height() / parent_width * font_width
            x_mid = np.where(self.frequencies == 0)[0]
            x_mid = int(x_mid[0]) if len(x_mid) > 0 else 0

            left = int(rect.left()) - (int(rect.left()) % x_grid_size)
            left = left if left > 0 else 0

            top = rect.top() - (rect.top() % y_grid_size)
            bottom = rect.bottom() - (rect.bottom() % y_grid_size)
            right_border = int(
                rect.right()) if rect.right() < len(self.frequencies) else len(
                    self.frequencies)

            x_range = list(range(x_mid, left, -x_grid_size)) + list(
                range(x_mid, right_border, x_grid_size))

            lines = [QLineF(x, rect.top(), x, bottom) for x in x_range] \
                    + [QLineF(rect.left(), y, rect.right(), y) for y in np.arange(top, bottom, y_grid_size)]

            painter.drawLines(lines)
            scale_x = view_rect.width() / parent_width
            scale_y = view_rect.height() / parent_width
            painter.scale(scale_x, scale_y)

            font_height = self.font_metrics.height()

            for x in x_range:
                value = self.value_with_suffix(self.center_freq +
                                               self.frequencies[x])
                font_width = self.font_metrics.width(value)
                painter.drawText(x / scale_x - font_width / 2,
                                 bottom / scale_y + font_height, value)
예제 #15
0
 def draw(self, qp: QPainter, end_pos: tuple or list = None) -> bool:
     """
     draws line in core object
     :param qp: QPainter of main UI object (core)
     :param end_pos: position of mouse if arrow on mouse
            if arrow has end position, end_pos param will be ignored
     """
     if self.end_pos:
         qp.drawLine(QLine(*self.start_pos, *self.end_pos))
         if self.need_arrow:
             ar1, ar2 = self.create_arrow(end_pos=self.end_pos)
             qp.drawLines(ar1, ar2)
         return False
     elif end_pos:
         start, end = self.get_start_and_end(end_pos)
         qp.drawLine(QLine(*start, *end))
         if self.need_arrow:
             ar1, ar2 = self.create_arrow(end_pos=end_pos)
             qp.drawLines(ar1, ar2)
         return True
예제 #16
0
파일: grid.py 프로젝트: Tikovka72/tabula
 def draw(self, qp: QtGui.QPainter):
     """
     draws grid and special lines
     :param qp: QPainter from main object
     """
     if not self.show or not self.grid:
         return
     qp.setPen(self.pen)
     special_lines = self.get_special_lines()
     if self.grid.get("x", []):
         qp.drawLines(*self.grid["x"])
     if self.grid.get("y", []):
         qp.drawLines(*self.grid["y"])
     pen = QtGui.QPen(QtGui.QColor(self.special_lines_color),
                      self.pen.width())
     pen.setStyle(self.line)
     qp.setPen(pen)
     if special_lines.get("x", []):
         qp.drawLines(*special_lines["x"])
     if special_lines.get("y", []):
         qp.drawLines(*special_lines["y"])
     if self.special_lines_for_drag_obj:
         qp.drawLines(*self.special_lines_for_drag_obj)
 def paintGrid(self, painter: QPainter, rect: QRectF, gridSize: int):
     left, top, right, bottom = rect.getCoords()
     x_min = (int(left - 1) // gridSize + 1) * gridSize
     y_min = (int(top - 1) // gridSize + 1) * gridSize
     x_max = (int(right) // gridSize) * gridSize
     y_max = (int(bottom) // gridSize) * gridSize
     # logging.debug(
     #     "x=(%s<=%s..%s<=%s) y=(%s<=%s..%s<=%s)",
     #     *(left, x_min, x_max, right),
     #     *(top, y_min, y_max, bottom)
     # )
     painter.setPen(QPen(Qt.gray, 2))
     painter.drawLines(QLineF(0, top, 0, bottom), QLineF(left, 0, right, 0))
     painter.setPen(QPen(Qt.gray, 1))
     painter.drawLines(
         QLineF(x, top, x, bottom)
         for x in range(x_min, x_max + 1, gridSize) if x)
     painter.drawLines(
         QLineF(left, y, right, y)
         for y in range(y_min, y_max + 1, gridSize) if y)
예제 #18
0
    def paintEvent(self, event):
        if self.x >= self.h_res / 2:
            if self.y >= self.v_res / 2:
                cuadrant = 4
            else:
                cuadrant = 1
        else:
            if self.y >= self.v_res / 2:
                cuadrant = 3
            else:
                cuadrant = 2

        opposite_cuadrants = {1: 3, 3: 1, 2: 4, 4: 2}
        cuadrant = opposite_cuadrants[cuadrant]
        corner = self.corner_positions[cuadrant]

        self.move(corner[0], corner[1])

        painter = QPainter()
        painter.begin(self)
        painter.setPen(QColor(75, 75, 75))

        # Paint border
        painter.drawRect(0, 0, self.rect_width, self.rect_height)

        # Paint the grid
        v_lines = []
        for i in range(self.M_SIZE[0] - 1):
            x = 1 + (i + 1) * self.pixel_size + self.grid_thickness * i
            line = QLineF(x, 1, x, self.rect_height - 1)
            v_lines.append(line)

        h_lines = []
        for i in range(self.M_SIZE[0] - 1):
            y = 1 + (i + 1) * self.pixel_size + self.grid_thickness * i
            line = QLineF(1, y, self.rect_width - 1, y)
            h_lines.append(line)

        painter.drawLines(v_lines)
        painter.drawLines(h_lines)

        # Paint zoomed pixels
        img = ImageGrab.grab(
            bbox=(self.true_corners[0][0], self.true_corners[0][1],
                  self.true_corners[1][0], self.true_corners[1][1]),
            all_screens=True)
        pixels = img.load()
        average = ImageStat.Stat(img).mean
        for row in range(self.M_SIZE[1]):
            for col in range(self.M_SIZE[0]):
                color = QColor(*pixels[col, row])

                painter.setPen(Qt.NoPen)
                painter.setBrush(color)
                painter.drawRect(
                    1 + col * self.pixel_size + col * self.grid_thickness,
                    1 + row * self.pixel_size + row * self.grid_thickness,
                    self.pixel_size, self.pixel_size)

                if (row == self.y - self.true_corners[0][1]
                        or col == self.x - self.true_corners[0][0]):
                    pixel = ((255 - average[0]), (255 - average[1]),
                             (255 - average[2]), 120)
                    color = QColor(*pixel)
                painter.setPen(Qt.NoPen)
                painter.setBrush(color)
                painter.drawRect(
                    1 + col * self.pixel_size + col * self.grid_thickness,
                    1 + row * self.pixel_size + row * self.grid_thickness,
                    self.pixel_size, self.pixel_size)
예제 #19
0
    def paintEvent(self, _):
        """
        重写绘制事件,参考 qfusionstyle.cpp 中的 CE_ProgressBarContents 绘制方法
        """
        option = QStyleOptionProgressBar()
        self.initStyleOption(option)

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(0.5, 0.5)

        vertical = option.orientation == Qt.Vertical  # 是否垂直
        inverted = option.invertedAppearance  # 是否反转
        # 是否显示动画
        indeterminate = (option.minimum == option.maximum) or (
            option.minimum < option.progress < option.maximum)
        rect = option.rect

        if vertical:
            rect = QRect(rect.left(), rect.top(), rect.height(),
                         rect.width())  # 翻转宽度和高度
            m = QTransform.fromTranslate(rect.height(), 0)
            m.rotate(90.0)
            painter.setTransform(m, True)

        maxWidth = rect.width()
        progress = max(option.progress, option.minimum)
        totalSteps = max(1, option.maximum - option.minimum)
        progressSteps = progress - option.minimum
        progressBarWidth = int(progressSteps * maxWidth / totalSteps)
        width = progressBarWidth  # 已进行的进度宽度
        radius = max(1, (min(width,
                             self.width() if vertical else self.height()) //
                         4) if self._radius is None else self._radius)

        reverse = (not vertical and
                   option.direction == Qt.RightToLeft) or vertical
        if inverted:
            reverse = not reverse

        # 绘制范围
        path = QPainterPath()
        if not reverse:
            progressBar = QRectF(rect.left(), rect.top(), width, rect.height())
        else:
            progressBar = QRectF(rect.right() - width, rect.top(), width,
                                 rect.height())

        # 切割范围
        path.addRoundedRect(progressBar, radius, radius)
        painter.setClipPath(path)

        # 绘制背景颜色
        painter.setPen(Qt.NoPen)
        painter.setBrush(self._color)
        painter.drawRoundedRect(progressBar, radius, radius)

        if not indeterminate:
            if self._animation:
                self._animation.stop()
                self._animation = None
        else:
            # 叠加颜色覆盖后出现类似线条间隔的效果
            color = self._color.lighter(320)
            color.setAlpha(80)
            painter.setPen(QPen(color, self._lineWidth))

            if self._animation:
                step = int(self._animation.animationStep() % self._lineWidth)
            else:
                step = 0
                self._animation = QProgressStyleAnimation(self._fps, self)
                self._animation.start()

            # 动画斜线绘制
            startX = int(progressBar.left() - rect.height() - self._lineWidth)
            endX = int(rect.right() + self._lineWidth)

            if (not inverted and not vertical) or (inverted and vertical):
                lines = [
                    QLineF(x + step, progressBar.bottom(),
                           x + rect.height() + step, progressBar.top())
                    for x in range(startX, endX, self._lineWidth)
                ]
            else:
                lines = [
                    QLineF(x - step, progressBar.bottom(),
                           x + rect.height() - step, progressBar.top())
                    for x in range(startX, endX, self._lineWidth)
                ]
            painter.drawLines(lines)
예제 #20
0
    def paintEvent(self, event):
        painter = QPainter(self)

        if self.main_ui.combo_interpolation.currentIndex() == 0:
            scale_mode = Qt.SmoothTransformation
        else:
            scale_mode = Qt.FastTransformation

        painter.drawImage(
            event.rect(),
            self.image.scaledToWidth(self.width * self.image_pixel_size,
                                     scale_mode))

        if self.agc_roi_from != None and self.agc_roi_to != None and not self.image_is_16bit:
            from_x, from_y, to_x, to_y = self.agc_roi_from.x(
            ), self.agc_roi_from.y(), self.agc_roi_to.x(), self.agc_roi_to.y()
            draw_rect(
                painter,
                from_x * self.image_pixel_size + self.image_pixel_size // 2,
                from_y * self.image_pixel_size + self.image_pixel_size // 2,
                (to_x - from_x) * self.image_pixel_size + 1,
                (to_y - from_y) * self.image_pixel_size + 1, 1, Qt.green)

            self.main_ui.update_agc_roi_label()

        if self.spotmeter_roi_from != None and self.spotmeter_roi_to != None:
            pen = QPen()
            pen.setColor(Qt.white)
            pen.setWidth(1)
            painter.setPen(pen)

            from_x, from_y, to_x, to_y = self.spotmeter_roi_from.x(
            ), self.spotmeter_roi_from.y(), self.spotmeter_roi_to.x(
            ), self.spotmeter_roi_to.y()

            from_x = from_x * self.image_pixel_size + self.image_pixel_size // 2 + 1
            from_y = from_y * self.image_pixel_size + self.image_pixel_size // 2 + 1
            to_x = to_x * self.image_pixel_size + self.image_pixel_size // 2 - 1
            to_y = to_y * self.image_pixel_size + self.image_pixel_size // 2 - 1

            cross_x = from_x + (to_x - from_x) / 2.0
            cross_y = from_y + (to_y - from_y) / 2.0

            if to_x - from_x > self.image_pixel_size or to_y - from_y > self.image_pixel_size:
                lines = [
                    QLineF(from_x, from_y, from_x + self.crosshair_width,
                           from_y),
                    QLineF(from_x, from_y, from_x,
                           from_y + self.crosshair_width),
                    QLineF(to_x, to_y, to_x, to_y - self.crosshair_width),
                    QLineF(to_x, to_y, to_x - self.crosshair_width, to_y),
                    QLineF(from_x, to_y, from_x, to_y - self.crosshair_width),
                    QLineF(from_x, to_y, from_x + self.crosshair_width, to_y),
                    QLineF(to_x, from_y, to_x, from_y + self.crosshair_width),
                    QLineF(to_x, from_y, to_x - self.crosshair_width, from_y)
                ]
                painter.drawLines(lines)

            lines = [
                QLineF(cross_x - self.crosshair_width, cross_y,
                       cross_x + self.crosshair_width, cross_y),
                QLineF(cross_x, cross_y - self.crosshair_width, cross_x,
                       cross_y + self.crosshair_width)
            ]
            painter.drawLines(lines)

            self.main_ui.update_spotmeter_roi_label()
예제 #21
0
class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.setObjectName("MainWindow")
        self.resize(Game.screenWidth, Game.screenHeight)

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("res/Instructions-icon.png"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.menubar = QtWidgets.QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)
        self.actionExit = QtWidgets.QAction(self)
        self.actionExit.setObjectName("actionExit")
        self.menuFile.addAction(self.actionExit)
        self.menubar.addAction(self.menuFile.menuAction())
        self.actionExit.triggered.connect(self.closeEvent)

        _translate = QtCore.QCoreApplication.translate
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.actionExit.setText(_translate("MainWindow", "Exit"))
        self.actionExit.setShortcut(_translate("MainWindow", "Ctrl+Q"))

        self.image = QImage(self.size(), QImage.Format_RGB32)
        self.image.fill(Qt.white)

        pen = QPen()
        pen.setBrush(QtGui.QBrush(Game.angleLineColor))
        self.painter = QPainter(self.image)
        self.painter.setPen(pen)

        self.stateMessage = ''

        #        self.hitSound = QtGui.

        self.homeUi()

    def homeUi(self):
        Game.state = Game.GameState.INTRO
        self.removeAllPaint()

        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")

        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        spacerItem = QtWidgets.QSpacerItem(20, 40,
                                           QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem, 2, 1, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 1, 2, 1, 1)

        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Orbitron")
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setFrameShadow(QtWidgets.QFrame.Raised)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 1, 1, 1, 1)

        spacerItem2 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 1, 0, 1, 1)

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setEnabled(True)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.pushButton.setFont(font)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("res/Instructions-icon.png"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 4, 1, 1, 1)
        self.pushButton.pressed.connect(self.insUi)

        spacerItem3 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem3, 0, 1, 1, 1)
        spacerItem4 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem4, 5, 1, 1, 1)

        self.playButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.playButton.setFont(font)
        self.playButton.setAutoFillBackground(False)
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap("res/Play-icon.png"), QtGui.QIcon.Normal,
                        QtGui.QIcon.Off)
        self.playButton.setIcon(icon1)
        self.playButton.setObjectName("playButton")
        self.gridLayout.addWidget(self.playButton, 3, 1, 1, 1)
        self.playButton.pressed.connect(self.gameTypeUi)

        self.setCentralWidget(self.centralwidget)

        self.retranslateHomeUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateHomeUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "HIT ME IF YOU CAN"))
        self.pushButton.setText(_translate("MainWindow", "Instructions"))
        self.playButton.setText(_translate("MainWindow", "Play Now"))

        self.show()

    def gameTypeUi(self):
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.p2c = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.p2c.setFont(font)
        self.p2c.setObjectName("p2c")
        self.gridLayout.addWidget(self.p2c, 5, 3, 1, 1)
        self.p2c.pressed.connect(self.p2cSelection)

        self.p2p = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.p2p.setFont(font)
        self.p2p.setObjectName("p2p")
        self.gridLayout.addWidget(self.p2p, 5, 1, 1, 1)
        self.p2p.pressed.connect(self.p2pSelection)

        spacerItem = QtWidgets.QSpacerItem(20, 100,
                                           QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem, 6, 1, 1, 3)
        spacerItem1 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Preferred)
        self.gridLayout.addItem(spacerItem1, 1, 1, 1, 3)

        self.gameType = QtWidgets.QLabel(self.centralwidget)
        self.gameType.setTextFormat(QtCore.Qt.RichText)
        self.gameType.setAlignment(QtCore.Qt.AlignCenter)
        self.gameType.setObjectName("gameType")

        self.gridLayout.addWidget(self.gameType, 0, 0, 1, 5)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem2, 5, 2, 1, 1)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem3, 5, 0, 1, 1)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem4, 5, 4, 1, 1)

        self.setCentralWidget(self.centralwidget)

        self.retranslateGameTypeUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateGameTypeUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.p2c.setText(_translate("MainWindow", "With Computer"))
        self.p2p.setText(_translate("MainWindow", "Two Player"))
        self.gameType.setText(
            _translate("MainWindow",
                       "<b style=\'font-size:25px\' >Choose The Game Type<b>"))

    def p2pSelection(self):
        Game.type = Game.Type.P2P
        self.playUi()

    def p2cSelection(self):
        Game.type = Game.Type.P2C
        self.playUi()

    def insUi(self):
        Game.state = Game.GameState.INSTRUCT

        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.backButton = QtWidgets.QPushButton(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.backButton.setFont(font)
        self.backButton.setObjectName("backButton")
        self.gridLayout.addWidget(self.backButton, 8, 1, 1, 1)
        self.backButton.pressed.connect(self.homeUi)

        spacerItem = QtWidgets.QSpacerItem(40, 20,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 8, 0, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 8, 2, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem2, 6, 0, 1, 3)

        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.plainTextEdit.setFont(font)
        self.plainTextEdit.setReadOnly(True)
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.gridLayout.addWidget(self.plainTextEdit, 3, 0, 1, 3)

        spacerItem3 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem3, 2, 0, 1, 3)

        self.label = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 3)

        self.setCentralWidget(self.centralwidget)

        self.retranslateInsUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateInsUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.backButton.setText(_translate("MainWindow", "Back to Mainmenu"))

        ins = '''
        1. Each of the players will have his turn.
        2. Player 1 can tune angle and speed by Key A and D.
        3. Player 2 can use Key Left Arrow and Right Arrow to do that.
        4. Space Key is used to select an angle or speed and advance.
        5. The opponent has a few time to take his position also using 
            A and D or Right and Left Arrow Button depending on his playing side.
        6. Player who can hit his opponent gains a point.
        7. Press P to pause the game and then Esc to get to the Mainmenu 
            or again P to resume
        8. Player gaining 5 points first, is the winner.
        
        '''

        self.plainTextEdit.setPlainText(_translate("MainWindow", ins))
        self.label.setText(_translate("MainWindow", "INSTRUCTION"))

        self.show()

    def playUi(self):
        Game.state = Game.GameState.PLAY

        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setObjectName("centralwidget")

        self.painter.fillRect(0, Game.screenHeight - Game.fieldHeight,
                              Game.screenWidth, Game.fieldHeight,
                              Game.fieldColor)
        self.painter.fillRect(Game.barPosX, Game.barPosY, Game.barWidth,
                              Game.barHeight, Game.fieldColor)

        self.setCentralWidget(self.centralwidget)

        self.show()

        global player1
        global player2
        player1 = Player((Game.player1limitX[0] + Game.player1limitX[1]) / 2)
        player2 = Player((Game.player2limitX[0] + Game.player2limitX[1]) / 2)

        # Main GameLoop Begins
        Game.turn = Game.Turn.P1

        self.startToMove()

        # Main GameLoop Ends

    def startToMove(self):
        Game.action = Game.Action.MOVE
        stone.gotoP()

        self.stateMessage = 'Take your position'
        self.paintField()
        QTimer.singleShot(2000, self.switchMoveToThrow)

        if Game.type == Game.Type.P2C and Game.turn == Game.Turn.P1:
            player2.playerX = random.randint(Game.player2limitX[0],
                                             Game.player2limitX[1])
            self.paintField()
        # ----------------------------- #
        #                               #
        #    for development purpose    #
        #                               #
        # ----------------------------- #
#
#        else:
#            player1.playerX = random.randint(Game.player1limitX[0], Game.player1limitX[1])
##
#        QTimer.singleShot(5, self.switchMoveToThrow)

#  Till here  #

    def switchMoveToThrow(self):
        self.stateMessage = 'Aim and Throw'
        Game.action = Game.Action.SET_ANGLE_FORCE
        angle_line.gotoStone()

        self.paintField()

        if Game.type == Game.Type.P2C and Game.turn == Game.Turn.P2:
            Game.action = Game.Action.THROW

            #            target = player2.playerX - player1.playerX# - Game.playerHeight / 2
            #            bar_dist = player2.playerX - Game.barPosX
            #            print(target - bar_dist, bar_dist)

            #            computer_input = [[target, bar_dist]]

            #to feed the model
            imageCrop = 300
            imageResize = (80, 30)

            computer_input = qimage2ndarray.byte_view(self.image)[imageCrop:]
            computer_input = cv2.resize(computer_input, imageResize)
            #            cv2.imshow(' ', computer_input)
            #            cv2.waitKey(0)
            #            cv2.destroyAllWindows()
            computer_input = computer_input.reshape((1, ) +
                                                    computer_input.shape)
            computer_input = computer_input / 255

            computer_output = Game.computer.predict(computer_input)
            angle = computer_output[0][0]
            velocity = computer_output[0][1]  # - 2
            #
            angle_line.current_angle = angle
            angle_line.current_vel = velocity

            #            print(angle, velocity)

            self.throw()
            self.paintField()
            angle_line.current_vel = Game.defaultForceLen

        # ----------------------------- #
        #                               #
        #    for development purpose    #
        #                               #
        # ----------------------------- #

#            Game.data.append([target, bar_dist, angle, a_velocity])
#            Game.dataCount += 1
#
#            if Game.dataCount >= 100:
#                x_train = []
#                y_train = []
#
#                for i in Game.data:
#                    x_train.append([i[0], i[2]])
#                    y_train.append([i[3]])
#
#                x_train = numpy.array(x_train)
#                y_train = numpy.array(y_train)
#
#                x_train = tf.keras.utils.normalize(x_train)
#                y_train = y_train / 110
#
#                Game.computer_vel.fit(x_train, y_train, epochs=3)
#
#                Game.data = []
#                Game.dataCount = 0
#
#        else:
#            Game.action = Game.Action.THROW
#            self.throw()

#  Till here  #

    def throw(self):
        prevX = stone.stoneX
        prevY = stone.stoneY
        v0 = angle_line.getVel()
        theta = angle_line.current_angle * math.pi / 180
        cos_theta = math.cos(theta)
        sin_theta = math.sin(theta)
        g = 9.8
        ground = Game.screenHeight - Game.fieldHeight - Game.stoneWidth

        t = 0

        if Game.turn == Game.Turn.P1:
            player = player1
            opponent = player2
        else:
            player = player2
            opponent = player1

        while stone.stoneY < ground:
            if Game.state == Game.GameState.PAUSED:
                QtTest.QTest.qWait(1000)
                continue

            x_ = v0 * t * cos_theta
            y_ = v0 * t * sin_theta - 0.5 * g * t * t

            #            if stone.stoneY >= opponent.playerY:
            #                print('distance travelled = ', x_)

            stone.stoneX = prevX + x_
            stone.stoneY = prevY - y_

            if stone.stoneY > ground:
                stone.stoneY = ground
                # unsuccessful
                self.stateMessage = 'Missed...'
                thread.start_new_thread(
                    self.playMusic,
                    ('res\\Woosh-Mark_DiAngelo-4778593.wav', 'ignore it'))
                break

            if stone.stoneX > Game.barPosX - Game.stoneWidth and stone.stoneX < Game.barPosX + Game.barWidth:
                if stone.stoneY > Game.barPosY - Game.stoneHeight:
                    # unsuccessful
                    self.stateMessage = 'Missed...'
                    thread.start_new_thread(
                        self.playMusic,
                        ('res\\Woosh-Mark_DiAngelo-4778593.wav', 'ignore it'))
                    #
                    #                    winsound.PlaySound('res\\Woosh-Mark_DiAngelo-4778593.wav', winsound.SND_FILENAME)
                    break

            if stone.stoneX > opponent.playerX - Game.stoneWidth and stone.stoneX < opponent.playerX + Game.playerWidth:
                if stone.stoneY > opponent.playerY - Game.stoneHeight:
                    # successful
                    self.stateMessage = 'Hit!!'
                    thread.start_new_thread(
                        self.playMusic,
                        ('res\\Realistic_Punch-Mark_DiAngelo-1609462330.wav',
                         'ignore it'))
                    #                    winsound.PlaySound('res\\Realistic_Punch-Mark_DiAngelo-1609462330.wav', winsound.SND_FILENAME)

                    #    for not development purpose    #
                    player.score += 1
                    break

            self.paintField()
            QtTest.QTest.qWait(50)

            # ----------------------------- #
            #                               #
            #    for development purpose    #
            #                               #
            # ----------------------------- #

            #            QtTest.QTest.qWait(1)

            #     Till here  #

            t += 0.3

        if player1.score >= Game.gameScore:
            #player1 wins
            if Game.type == Game.Type.P2P:
                self.stateMessage = 'Player 1 wins <br> Press any key to continue'
            else:
                self.stateMessage = 'You Win..! <br> Press any key to continue'

            thread.start_new_thread(
                self.playMusic,
                ('res\\Applauding-and-cheering.mp3', 'ignore it'))
            Game.state = Game.GameState.GAMEOVER
        elif player2.score >= Game.gameScore:
            #player2 wins
            if Game.type == Game.Type.P2P:
                self.stateMessage = 'Player 2 wins <br> Press any key to continue'
                thread.start_new_thread(
                    self.playMusic,
                    ('res\\Applauding-and-cheering.mp3', 'ignore it'))
            else:
                self.stateMessage = 'You lose..! <br> Press any key to continue'
                thread.start_new_thread(
                    self.playMusic, ('res\\fail-trombone-01.mp3', 'ignore it'))
            Game.state = Game.GameState.GAMEOVER
        else:
            if Game.turn == Game.Turn.P1:
                Game.turn = Game.Turn.P2
            else:
                Game.turn = Game.Turn.P1

            QTimer.singleShot(500, self.startToMove)

            # ----------------------------- #
            #                               #
            #    for development purpose    #
            #                               #
            # ----------------------------- #

#            QTimer.singleShot(1, self.startToMove)

#     Till here  #

    def keyPressEvent(self, event):
        #        print(event)
        if event.key() == Qt.Key_P and Game.state == Game.GameState.PLAY:
            Game.state = Game.GameState.PAUSED
            self.prevMessage = self.stateMessage
            self.stateMessage = 'Paused'
            self.paintField()

        elif Game.state == Game.GameState.PAUSED:
            if event.key() == Qt.Key_P:
                Game.state = Game.GameState.PLAY
                self.stateMessage = self.prevMessage
                self.paintField()
            elif event.key() == Qt.Key_Escape:
                QTimer.singleShot(50, self.homeUi)

        elif Game.state == Game.GameState.PLAY and Game.action != Game.Action.THROW:
            if Game.turn == Game.Turn.P1:
                if Game.type == Game.Type.P2P and Game.action == Game.Action.MOVE:
                    if event.key() == Qt.Key_Left and Game.player2limitX[
                            0] < player2.playerX:
                        player2.move(-1)
                    elif event.key(
                    ) == Qt.Key_Right and player2.playerX < Game.player2limitX[
                            1]:
                        player2.move(1)

                elif Game.action == Game.Action.SET_ANGLE_FORCE:
                    if event.key() == Qt.Key_W and angle_line.getAngle(
                    ) < Game.player1AngleLimit[1]:
                        angle_line.change(1)
                    elif event.key() == Qt.Key_S and Game.player1AngleLimit[
                            0] < angle_line.getAngle():
                        angle_line.change(-1)
                    elif event.key(
                    ) == Qt.Key_A and angle_line.getVel() > Game.minForceLen:
                        angle_line.changeVel(-1)
                    elif event.key(
                    ) == Qt.Key_D and Game.maxForceLen > angle_line.getVel():
                        angle_line.changeVel(1)
                    elif event.key() == Qt.Key_Space:
                        Game.action = Game.Action.THROW
                        self.throw()
                        angle_line.current_vel = Game.defaultForceLen

                else:
                    return
            else:
                if Game.action == Game.Action.MOVE:
                    if event.key(
                    ) == Qt.Key_A and Game.player1limitX[0] < player1.playerX:
                        player1.move(-1)
                    elif event.key(
                    ) == Qt.Key_D and player1.playerX < Game.player1limitX[1]:
                        player1.move(1)

                elif Game.action == Game.Action.SET_ANGLE_FORCE:
                    if event.key() == Qt.Key_Down and angle_line.getAngle(
                    ) < Game.player2AngleLimit[1]:
                        angle_line.change(1)
                    elif event.key() == Qt.Key_Up and Game.player2AngleLimit[
                            0] < angle_line.getAngle():
                        angle_line.change(-1)
                    elif event.key(
                    ) == Qt.Key_Left and Game.maxForceLen > angle_line.getVel(
                    ):
                        angle_line.changeVel(1)
                    elif event.key() == Qt.Key_Right and angle_line.getVel(
                    ) > Game.minForceLen:
                        angle_line.changeVel(-1)
                    elif event.key() == Qt.Key_Space:
                        Game.action = Game.Action.THROW
                        self.throw()
                        angle_line.current_vel = Game.defaultForceLen

                else:
                    return

            self.paintField()

        elif Game.state == Game.GameState.GAMEOVER:
            QTimer.singleShot(50, self.homeUi)


#        print(self.position)

    def removeAllPaint(self):
        self.painter.fillRect(self.image.rect(), Qt.white)
        self.update()

    def paintField(self):
        self.removeAllPaint()

        self.painter.fillRect(0, Game.screenHeight - Game.fieldHeight,
                              Game.screenWidth, Game.fieldHeight,
                              Game.fieldColor)
        self.painter.fillRect(Game.barPosX, Game.barPosY, Game.barWidth,
                              Game.barHeight, Game.fieldColor)

        self.painter.fillRect(player1.playerX, player1.playerY,
                              Game.playerWidth, Game.playerHeight,
                              Game.playerColor)
        self.painter.fillRect(player2.playerX, player2.playerY,
                              Game.playerWidth, Game.playerHeight,
                              Game.playerColor)
        self.painter.fillRect(stone.stoneX, stone.stoneY, Game.stoneWidth,
                              Game.stoneWidth, Game.stoneColor)

        self.scoreText1 = '<b style="font-size:20px;">Player 1 : ' + str(
            player1.score) + '<\b>'

        if Game.type == Game.Type.P2P:
            self.scoreText2 = '<b style="font-size:20px;">Player 2 : ' + str(
                player2.score) + '<\b>'
        else:
            self.scoreText2 = '<b style="font-size:20px;">Computer : ' + str(
                player2.score) + '<\b>'

        self.message = '<b style="font-size:40px;">' + self.stateMessage + '<\b>'

        text1 = QtGui.QStaticText(self.scoreText1)
        text1.setTextFormat(Qt.RichText)
        text2 = QtGui.QStaticText(self.scoreText2)
        text2.setTextFormat(Qt.RichText)
        message = QtGui.QStaticText(self.message)
        message.setTextFormat(Qt.RichText)
        self.painter.drawStaticText(Game.scoreText1PosX, Game.scoreText1PosY,
                                    text1)
        self.painter.drawStaticText(Game.scoreText2PosX, Game.scoreText2PosY,
                                    text2)
        self.painter.drawStaticText(Game.stateMessageBoxX,
                                    Game.stateMessageBoxY, message)

        if Game.action == Game.Action.SET_ANGLE_FORCE:
            self.painter.drawLines(angle_line.getLines())

        self.update()

    def paintEvent(self, event):
        canvas = QPainter(self)
        if Game.state == Game.GameState.PLAY or Game.state == Game.GameState.GAMEOVER:
            canvas.drawImage(self.rect(), self.image, self.image.rect())
        elif Game.state == Game.GameState.PAUSED:
            message = '<b style="font-size:40px;">PAUSED<br> Press P to play or Esc to exit<\b>'
            message = QtGui.QStaticText(message)
            message.setTextFormat(Qt.RichText)
            canvas.drawStaticText(Game.stateMessageBoxX, Game.stateMessageBoxY,
                                  message)

    def playMusic(self, file, ignored):
        playsound(file)

    def closeEvent(self, event):
        #        QCoreApplication.quit()

        # ----------------------------- #
        #                               #
        #    for development purpose    #
        #                               #
        # ----------------------------- #

        #        numpy.save('modelDataReal.npy', Game.data)
        #        Game.computer_vel.save('model6')

        # till here

        sys.exit()
예제 #22
0
class AniState:
    """Wrapper class around QPainter to ease its usage."""
    def __init__(self, widget, frame, time, dt, center=False):
        self._painter = QPainter(widget)
        self._painter.setRenderHint(QPainter.Antialiasing, True)
        if center:
            self._painter.translate(widget.width() / 2, widget.height() / 2)

        self.width = widget.width()
        self.height = widget.height()
        self.frame = frame
        self.time = time
        self.dt = dt

    def color(self, value):
        """
        Sets the border color. The input value might be ``None`` to use
        no border, a tuple consisting of (r, g, b, [a]), a string or an
        integer representing the color, or a QColor/QPen itself.
        """
        width = self._painter.pen().widthF()
        if value is None:
            self._painter.setPen(Qt.NoPen)
        elif isinstance(value, tuple):
            self._painter.setPen(QPen(QColor(*value), width))
        elif isinstance(value, (str, int)):
            self._painter.setPen(QPen(QColor(value), width))
        elif isinstance(value, QColor):
            self._painter.setPen(QPen(value, width))
        elif isinstance(value, QPen):
            self._painter.setPen(value)
        return self

    def fill(self, value):
        """
        Sets the fill color. The input value might be ``None`` to use
        no fill, a tuple consisting of (r, g, b, [a]), a string or an
        integer representing the color, or a QColor/QBrush itself.
        """
        if value is None:
            self._painter.setBrush(Qt.NoBrush)
        elif isinstance(value, tuple):
            self._painter.setBrush(QBrush(QColor(*value)))
        elif isinstance(value, (str, int)):
            self._painter.setBrush(QBrush(QColor(value)))
        elif isinstance(value, QColor):
            self._painter.setBrush(QBrush(value))
        elif isinstance(value, QBrush):
            self._painter.setBrush(value)
        return self

    def size(self, size):
        """
        Sets the size for lines and points.
        """
        pen = self._painter.pen()
        pen.setWidthF(size)
        self._painter.setPen(pen)
        return self

    def line(self, x1, y1, x2=None, y2=None):
        """
        Draws a line between the input positions.

        If list/tuples are given as the first two arguments, they should
        consist of two elements representing elements in a position vector.
        """
        if isinstance(x1, (tuple, list)):
            x2 = y1
            x1, y1 = x1
        if isinstance(x2, (tuple, list)):
            x2, y2 = x2
        self._painter.drawLine(x1, y1, x2, y2)
        return self

    def point(self, x, y=None):
        """
        Draws a single point.

        If a list/tuple is supplied as the first argument, it should
        consist of two elements representing elements in a position vector.
        """
        if isinstance(x, (tuple, list)):
            x, y = x
        self._painter.drawPoint(x, y)
        return self

    def points(self, values):
        """
        Draws a series of points. If the first element of the list of
        values is a list/tuple, then the following must be the same type.
        """
        assert len(values) % 2 == 0
        if isinstance(values[0], (tuple, list)):
            self._painter.drawPoints(*[QPointF(x, y) for x, y, in values])
        else:
            self._painter.drawPoints(*[QPointF(values[i], values[i + 1])
                                       for i in range(0, len(values), 2)])

    def lines(self, values, closed=False):
        """
        Draws a series of connected lines. If the first element of the list
        of values is a list/tuple, then the following must be the same type.

        If ``closed``, the first point will be connected to the last.
        """
        assert len(values) > 4 and len(values) % 2 == 0
        if isinstance(values[0], (tuple, list)):
            self._painter.drawLines(*[
                QLineF(
                    values[i - 1][0], values[i - 1][1],
                    values[i][0],     values[i][0]
                )
                for i in range(0 if closed else 1, len(values))
            ])
        else:
            self._painter.drawLines(*[
                QLineF(
                    values[i - 2], values[i - 1],
                    values[i],     values[i + 1]
                )
                for i in range(0 if closed else 2, len(values), 2)
            ])
        return self

    def box(self, x, y, width, height):
        """Draws a box at the given position with the given size."""
        self._painter.drawRect(x, y, width, height)

    def rect(self, x1, y1, x2, y2):
        """Wrapper around anistate.box(x1, y1, x2 - x1, y2 - y1)."""
        if x2 < x1:
            x1, x2 = x2, x1
        if y2 < y1:
            y1, y2 = y2, y1
        self._painter.drawRect(x1, y1, x2 - x1, y2 - y1)

    def circle(self, x, y, radius):
        """Draws a centered circle at the given position and radius."""
        self._painter.drawEllipse(QPointF(x, y), radius, radius)

    def poly(self, values):
        """Draws a filled polygon with the shape of the input values."""
        assert len(values) % 2 == 0
        if isinstance(values[0], (tuple, list)):
            self._painter.drawPolygon(*[QPointF(x, y) for x, y, in values])
        else:
            self._painter.drawPolygon(*[QPointF(values[i], values[i + 1])
                                        for i in range(0, len(values), 2)])
        return self
예제 #23
0
    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget=None):
        fillColor = self.color.darker(150) if (option.state & QStyle.State_Selected) else self.color

        if option.state & QStyle.State_MouseOver:
            fillColor = fillColor.lighter(125)

        lod = option.levelOfDetailFromTransform(painter.worldTransform())
        if lod < 0.2:
            if lod < 0.125:
                painter.fillRect(QRectF(0, 0, 110, 70), fillColor)
                return

            b = painter.brush()
            painter.setBrush(fillColor)
            painter.drawRect(13, 13, 97, 57)
            painter.setBrush(b)
            return

        oldPen = painter.pen()
        pen = oldPen
        width = 0
        if option.state & QStyle.State_Selected:
            width += 2

        pen.setWidth(width)
        b = painter.brush()
        f = 120 if option.state & QStyle.State_Sunken else 100
        painter.setBrush(QBrush(fillColor.darker(f)))
        painter.drawRect(QRect(14, 14, 79, 39))
        painter.setBrush(b)

        if lod >= 1:
            painter.setPen(QPen(Qt.gray, 1))
            painter.drawLine(15, 54, 94, 54)
            painter.drawLine(94, 53, 94, 15)
            painter.setPen(QPen(Qt.black, 0))

        if lod >= 2:
            font = QFont("Times", 10)
            font.setStyleStrategy(QFont.ForceOutline)
            painter.setFont(font)
            painter.save()
            painter.scale(0.1, 0.1)
            painter.drawText(170, 180, "Model: VSC-2000 (Very Small Chip) at {}x{}".format(self.x, self.y))
            painter.drawText(170, 200, "Serial number: DLWR-WEER-123L-ZZ33-SDSJ")
            painter.drawText(170, 220, "Manufacturer: Chip Manufacturer")

        lines = []
        if lod >= 0.5:
            for i in np.arange(0, 10, 1 if lod > 0.5 else 2):
                lines.append(QLineF(18 + 7 * i, 13, 18 + 7 * i, 5))
                lines.append(QLineF(18 + 7 * i, 54, 18 + 7 * i, 62))

            for i in np.arange(0, 6, 1 if lod > 0.5 else 2):
                lines.append(QLineF(5,18 + 5 * i, 13, 18 + 5 * i))
                lines.append(QLineF(94, 18 + 5 * i, 102, 18 + 5 * i))

        if lod >= 0.4:
            lineData = [
                QLineF(25, 35, 35, 35),
                QLineF(35, 30, 35, 40),
                QLineF(35, 30, 45, 35),
                QLineF(35, 40, 45, 35),
                QLineF(45, 30, 45, 40),
                QLineF(45, 35, 55, 35),
            ]
            lines.extend(lineData)

        painter.drawLines(lines)

        if len(self.stuff) > 1:
            p = painter.pen()
            painter.setPen(QPen(Qt.red, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.setBrush(Qt.NoBrush)
            path = QPainterPath()
            path.moveTo(self.stuff[0])
            for i in np.arange(len(self.stuff)):
                path.lineTo(self.stuff[i])
            painter.drawPath(path)
            painter.setPen(p)
예제 #24
0
class QtRenderer(Renderer):
    """An implementation of :class:`~renderer.Renderer` for PyQt5.
       
       This renderer will draw on any `QPaintDevice`
    """
    def __init__(self, paint_device):
        """Creates a new renderer based on a QPaintDevice pd"""
        self._grid_pen = QPen(QColor(0x808080))
        self._grid_pen.setStyle(Qt.DashLine)
        self._painter = None
        Renderer.__init__(self, paint_device)

    def set_canvas(self, canvas):
        """Tell the renderer to draw on canvas
        The type of canvas is implementation-dependent"""
        if self._painter is not None:
            self._painter.restore()
            self._painter.restore()
            self._painter.end()
        
        self._paintdevice = canvas
        self._painter = QPainter(canvas)
        self._painter.setRenderHint(QPainter.Antialiasing)

        # invert the y axis
        self._painter.scale(1,-1)
        self._painter.translate(0,-canvas.height())

        Renderer.set_canvas(self,canvas)

    def _get_canvas_size(self,pd):
        """Get the canvas size tuple (width,height)"""
        return (pd.width(), pd.height())

    def push_state(self):
        """Store the current state on the stack.
        Current state includes default pose, pen and brush"""
        ### FIXME store things
        self._painter.save()

    def pop_state(self):
        """Restore the last saved state from the stack
        The state includes default pose, pen and brush"""
        ### FIXME store things
        self._painter.restore()

    def _calculate_bounds(self):
        transform = self._painter.worldTransform().inverted()[0]
        xs,ys = zip(
                    transform.map(0.0,0.0),
                    transform.map(0.0,float(self.size[1])),
                    transform.map(float(self.size[0]),float(self.size[1])),
                    transform.map(float(self.size[0]),0.0)
                    )

        self._bounds = (min(xs), min(ys), max(xs), max(ys))

    def _draw_grid(self):
        self.reset_pose()
        self._painter.setPen(self._grid_pen)
        xmin, ymin, xmax, ymax = self._bounds

        # Determine min/max x & y line indices:
        x_ticks = (int(xmin//self._grid_spacing), int(xmax//self._grid_spacing + 1))
        y_ticks = (int(ymin//self._grid_spacing), int(ymax//self._grid_spacing + 1))

        self._painter.drawLines(
            [QLineF(xmin, i * self._grid_spacing,
                    xmax, i * self._grid_spacing)
                for i in range(*y_ticks)])
        self._painter.drawLines(
            [QLineF(i * self._grid_spacing, ymin,
                    i * self._grid_spacing, ymax)
                for i in range(*x_ticks)])

    def scale(self, factor):
        """Scale drawing operations by factor
        To be implemented in subclasses."""
        self._painter.scale(factor,factor)

    def rotate(self, angle):
        """Rotate canvas by angle (in radians)
        To be implemented in subclasses."""
        self._painter.rotate(degrees(angle))

    def translate(self, dx, dy):
        """Translate canvas by dx, dy
        To be implemented in subclasses."""
        self._painter.translate(dx,dy)

    def clear_screen(self):
        """Erases the current screen with a white brush"""
        self._painter.save()
        self._painter.resetTransform()
        self.set_pen(0xFFFFFF)
        self.set_brush(0xFFFFFF)
        self.draw_rectangle(0,0,self.size[0],self.size[1])
        self._painter.restore()
        Renderer.clear_screen(self)

    @staticmethod
    def __qcolor(color):
        """Returns qcolor for a given ARGB color"""
        c = QColor(color)
        if color > 0xFFFFFF:
            c.setAlpha((color >> 24) & 0xFF)
        return c

    def set_pen(self,color=0, thickness=0):
        """Sets the line color and thickness.
        Color is interpreted as 0xAARRGGBB."""
        if color is None:
            self._painter.setPen(Qt.NoPen)
        else:
            self._painter.setPen(QPen(self.__qcolor(color),thickness))

    def set_brush(self,color):
        """Sets the fill color.
        Color is interpreted as 0xAARRGGBB."""
        if color is None:
            self._painter.setBrush(Qt.NoBrush)
        else:
            self._painter.setBrush(self.__qcolor(color))

    def draw_polygon(self,points):
        """Draws a polygon.
        Expects a list of points as a list of tuples or as a numpy array."""
        self._painter.drawPolygon(QPolygonF([QPointF(*point[:2]) for point in points]))

    def draw_ellipse(self, cx, cy, ra, rb = None):
        """Draws an ellipse."""
        if rb is None:
            rb = ra
        self._painter.drawEllipse(QRectF(cx-ra,cy-ra,2*ra,2*rb))

    def draw_rectangle(self, x, y, w, h):
        """Draws a rectangle."""
        self._painter.drawRect(QRectF(x,y,w,h))

    def draw_text(self, text, x, y, bgcolor = 0):
        """Draws a text string at the defined position."""
        pass

    def draw_line(self, x1, y1, x2, y2):
        """Draws a line using the current pen from (x1,y1) to (x2,y2)"""
        self._painter.drawLine(QLineF(x1,y1,x2,y2))
        
    def draw_point(self,x,y):
        """Draw a single point using the current pen at (x,y)"""
        self._painter.drawPoint(QPointF(x,y))
        
    def draw_points(self,points):
        """Draw a set of points, given as [(x,y)], using the current pen"""
        self._painter.drawPoints(QPolygonF([QPointF(x,y) for x,y in points]))
예제 #25
0
class ImageViewer(QWidget):
    MousePosChangedSignal = pyqtSignal([QPointF], name='Mouse Pos Changed')
    ViewPointChangeSignal = pyqtSignal([QPointF, QPointF, float, float],
                                       name='View Point Changed')

    def __init__(self):
        super(ImageViewer, self).__init__()
        self.setMouseTracking(True)
        # moniter = QApplication.desktop().size()
        moniter = QApplication.primaryScreen().size()
        self.resize(int(moniter.width() / 1.5), int(moniter.height() / 1.5))
        self.initUi()

    def initUi(self):
        self.ImagePath = None  # 原始图片路径
        self.Image = None  # 图像

        self.cropPolygon = None  # 裁剪边框

        # private property
        self.mousePos = QPointF(0, 0)
        self.mouseLeftButtonDown = False

        self.scale = 1  # 比例
        self.offset = QPointF(0, 0)  # 初始坐标

        self.backgroundColor = QColor("#898989")
        # button
        self.zoomInBtn = QPushButton(QIcon('images/icons/zoom-in.png'), '')
        self.zoomInBtn.setToolTip('Zoom In')
        self.zoomInBtn.clicked.connect(self.zoomIn)
        self.zoomOutBtn = QPushButton(QIcon('images/icons/zoom-out.png'), '')
        self.zoomOutBtn.setToolTip('Zoom Out')
        self.zoomOutBtn.clicked.connect(self.zoomOut)
        self.reloadBtn = QPushButton(QIcon('./images/icons/expand.png'), '')
        self.reloadBtn.setToolTip('Center')
        self.reloadBtn.clicked.connect(self.setImageCenter)

        # layout
        self.mainLayout = QVBoxLayout()
        self.mainLayout.addStretch(1)
        self.toolBox = QHBoxLayout()
        self.toolBox.addStretch(1)
        self.toolBox.addWidget(self.zoomInBtn)
        self.toolBox.addWidget(self.zoomOutBtn)
        self.toolBox.addWidget(self.reloadBtn)
        self.mainLayout.addLayout(self.toolBox)
        self.setLayout(self.mainLayout)

    def paintEvent(self, event):
        if self.mouseLeftButtonDown:
            self.setCursor(Qt.SizeAllCursor)
        else:
            self.setCursor(Qt.ArrowCursor)
        self.backgroundPalette = QPalette()
        self.backgroundPalette.setColor(self.backgroundRole(),
                                        self.backgroundColor)
        self.setPalette(self.backgroundPalette)
        self.setAutoFillBackground(True)
        self.pt = QPainter()
        if self.Image:
            renderImage = self.renderImage()
            scaledImage = renderImage.scaled(
                int(renderImage.size().width() * self.scale),
                int(renderImage.size().height() * self.scale))
            self.pt.begin(self)
            self.pt.drawImage(self.offset, scaledImage)
            self.pt.end()
        self.draw_axis()

    def draw_axis(self):
        # get size of widget
        width = self.size().width()
        height = self.size().height()
        axisLength = 100
        axisOriginPoint = QPoint(20, height - 20)
        PLU = QPoint(0, -10) + axisOriginPoint
        PL = QPoint(0, 0) + axisOriginPoint
        PR = QPoint(axisLength, 0) + axisOriginPoint
        PRU = QPoint(axisLength, -10) + axisOriginPoint
        textRect = QRect(PL - QPoint(0, 20), PR)
        self.pt.begin(self)
        lines = [QLineF(PLU, PL), QLineF(PL, PR), QLineF(PR, PRU)]
        self.pt.drawLines(lines)
        self.pt.drawText(textRect, Qt.AlignCenter,
                         str(np.around(axisLength / self.scale, 2)) + 'PX')
        self.pt.end()

    def resizeEvent(self, event: QResizeEvent) -> None:
        pass

    def wheelEvent(self, event: QWheelEvent) -> None:
        step = event.angleDelta().y() / 8 / 150  # one step, 0.1
        pos = event.position()
        print('鼠标滚轮滚动, X: %s, Y: %s, Step: %s' % (pos.x(), pos.y(), step))
        if step > 0:
            self.zoomIn(pos=pos, p=abs(step))
        else:
            self.zoomOut(pos=pos, p=abs(step))

    def mousePressEvent(self, event: QMouseEvent) -> None:
        if event.button() == Qt.LeftButton:
            print('鼠标左键单击: %s, %s' % (event.x(), event.y()))
            self.mouseLeftButtonDown = True
            self.mousePos = event.pos()

    def mouseReleaseEvent(self, event: QMouseEvent) -> None:
        if event.button() == Qt.LeftButton:
            print('鼠标左键释放: %s, %s' % (event.x(), event.y()))
            self.mouseLeftButtonDown = False

    def mouseMoveEvent(self, event: QMouseEvent) -> None:
        if self.mouseLeftButtonDown:
            print('鼠标左键拖移: %s, %s' % (event.x(), event.y()))
            posDiff = event.pos() - self.mousePos
            print('移动量: %s, %s' % (posDiff.x(), posDiff.y()))
            # self.offset = self.offset + posDiff
            self.setViewPoint(offset=self.offset + posDiff)

        self.mousePos = event.pos()
        self.MousePosChangedSignal.emit(self._real2pix(event.pos()))
        self.update()

    def keyPressEvent(self, event: QKeyEvent) -> None:
        pass

    def _pix2real(self, pos: QPointF):
        return pos * self.scale + self.offset

    def _real2pix(self, pos: QPointF):
        return (pos - self.offset) / self.scale

    def setImage(self, imagePath=None, image=None):

        if not os.path.exists(imagePath) and image == None:
            raise Exception('Error image path.')
        self.initUi()
        try:
            if image and type(image) == QImage:
                self.Image = image
            else:
                self.ImagePath = imagePath
                self.Image = QImage(self.ImagePath)
            self.update()

        except Exception as e:
            raise e
        self.setImageCenter()

    def setImageCenter(self):
        if not self.Image:
            return None
        self.setViewPoint(
            scale=min(self.size().width() / self.Image.size().width(),
                      self.size().height() / self.Image.size().height()))
        # self.setScale(min(self.size().width() / self.Image.size().width(),
        #                   self.size().height() / self.Image.size().height()))
        offsetX = (self.size().width() - self.Image.width() * self.scale) / 2
        offsetY = (self.size().height() - self.Image.height() * self.scale) / 2
        self.setViewPoint(offset=QPointF(offsetX, offsetY))
        self.update()

    def setViewPoint(self, offset=None, scale=None):
        if not self.Image:
            return None
        oldOffset = False
        oldScale = False
        if offset and not offset == self.offset:
            oldOffset = self.offset
            self.offset = offset
        if scale and not scale == self.scale:
            oldScale = self.scale
            self.scale = scale
        if oldOffset or oldScale:
            self.ViewPointChangeSignal.emit(
                oldOffset if oldOffset else self.offset, self.offset,
                oldScale if oldScale else self.scale, self.scale)
            self.update()

    def zoomIn(self, pos=None, p=0.1):
        if not self.Image:
            return None
        if not pos:
            pos = QPointF(self.size().width() / 2, self.size().height() / 2)
        self.setViewPoint(scale=self.scale * (1 + p),
                          offset=self.offset - (pos - self.offset) * p)
        self.update()

    def zoomOut(self, pos=None, p=0.1):
        if not self.Image:
            return None
        if not pos:
            pos = QPointF(self.size().width() / 2, self.size().height() / 2)
        self.setViewPoint(scale=self.scale * (1 - p),
                          offset=self.offset + (pos - self.offset) * p)
        self.update()

    def setCropPolygon(self, polygon: QPolygonF):
        self.cropPolygon = polygon
        self.update()

    def renderImage(self, remove_useless_background=False):
        if not self.Image:
            return
        paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32)
        paintedImage.fill(Qt.transparent)
        painter = QPainter(paintedImage)
        if self.cropPolygon:
            painterPath = QPainterPath()
            painterPath.addPolygon(self.cropPolygon)
            painter.setClipPath(painterPath)
        painter.drawImage(QPoint(), self.Image)
        painter.end()
        if remove_useless_background:
            return paintedImage.copy(painterPath.boundingRect().toRect())
        else:
            return paintedImage
예제 #26
0
class GraphicCore(QtWidgets.QWidget):
    """
    main class with UI
    """
    STANDARD_SIZE = 640, 480
    OFFSET_MAGNET = 5

    def __init__(self, manager: Manager):
        super().__init__()
        self.qp = QPainter()
        self.manager = manager
        self.setAcceptDrops(True)
        self.setMouseTracking(True)

    def __init_ui__(self):
        self.setWindowTitle("tabula")
        self.setMinimumSize(640, 480)
        self.resize(*self.STANDARD_SIZE)
        self.showMaximized()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.setObjectName("core")
        self.setStyleSheet("QWidget#core {background-color: white}")
        self.setFocus()

        self.create_settings()
        self.manager.settings_window.show_sett(self)

    def create_settings(self):
        self.manager.settings_window.add_settings(self,
                                                  SettingsWindow.Title,
                                                  name="Положение экрана")

        self.manager.settings_window.add_settings(
            self,
            SettingsWindow.SettOneLineEdit,
            name="Положение центра по горизонтали",
            standard_values=(
                self.manager.grid_manager.zero_point_dot.get_pos()[0], ),
            int_only=True,
            default_values_to_return=(self.size().width() // 2, ),
            callback=(self.call_back_zero_pos_width, ),
            call_update_all=self.call_set_zero_pos_x)

        self.manager.settings_window.add_settings(
            self,
            SettingsWindow.SettOneLineEdit,
            name="Положение центра по вертикали",
            standard_values=(
                self.manager.grid_manager.zero_point_dot.get_pos()[1], ),
            int_only=True,
            default_values_to_return=(self.size().height() // 2, ),
            callback=(self.call_back_zero_pos_height, ),
            call_update_all=self.call_set_zero_pos_y)

        self.manager.settings_window.add_settings(
            self,
            SettingsWindow.Line,
        )
        self.manager.settings_window.add_settings(self,
                                                  SettingsWindow.Title,
                                                  name="Сетка")

        self.manager.settings_window.add_settings(
            self,
            SettingsWindow.SettOneLineEdit,
            name="Размер сетки",
            standard_values=(self.manager.grid_manager.grid.get_step(), ),
            int_only=True,
            default_values_to_return=(
                self.manager.grid_manager.grid.get_step(), ),
            callback=(self.call_back_grid_size, ),
            call_update_all=self.call_set_grid_size)

        self.manager.settings_window.add_settings(
            self,
            SettingsWindow.SettCheckbox,
            name="Сетка",
            standard_values=(("вкл", True), ),
            default_values_to_return=(True, ),
            callback=(self.call_back_grid_show, ),
            call_update_all=self.call_set_grid_show)

    def call_back_zero_pos_width(self, x: int):
        """
        callback for settings window. This is necessary to move zero point horizontally
        settings window -> core
        """

        self.manager.grid_manager.zero_point_dot.move_event(
            x + self.width() // 2,
            self.manager.grid_manager.zero_point_dot.get_pos()[1])

        self.manager.grid_manager.grid.set_offset_by_zero_point()
        self.manager.grid_manager.grid.regenerate_grid()
        self.update()

    def call_back_zero_pos_height(self, y: int):
        """
        callback for settings window. This is necessary to move zero point vertically
        settings window -> core
        """
        self.manager.grid_manager.zero_point_dot.move_event(
            self.manager.grid_manager.zero_point_dot.get_pos()[0],
            y + self.height() // 2)
        self.manager.grid_manager.grid.set_offset_by_zero_point()
        self.manager.grid_manager.grid.regenerate_grid()
        self.update()

    def call_set_zero_pos(self) -> Tuple[int, int]:
        """
        gives right zero point position to settings window
        core -> settings window
        :return: position in tuple format (x, y)
        """
        x_left, y_up = self.manager.grid_manager.zero_point_dot.get_pos()
        x = x_left - self.width() // 2
        y = y_up - self.height() // 2
        return x, y

    def call_set_zero_pos_x(self) -> int:
        return self.call_set_zero_pos()[0]

    def call_set_zero_pos_y(self) -> int:
        return self.call_set_zero_pos()[1]

    def call_back_grid_show(self, show: bool):
        """
        callback for settings window. This is necessary to change grid showing
        settings window -> core
        """
        if show and not self.manager.grid_manager.grid.show:
            self.manager.grid_manager.grid.toggle_show()
        elif not show and self.manager.grid_manager.grid.show:
            self.manager.grid_manager.grid.toggle_show()
        self.update()

    def call_back_grid_size(self, step: int):
        """
        callback for settings window. This is necessary to change grid size
        settings window -> core
        """
        self.manager.grid_manager.grid.change_step(step)
        self.manager.grid_manager.grid.set_offset_by_zero_point()
        self.manager.grid_manager.grid.regenerate_grid()
        self.update()

    def call_set_grid(self) -> Tuple[bool, int]:
        """
        gives grid's showing and step
        core -> settings window
        :return: tuple: (show, step)
        """
        return self.manager.grid_manager.grid.show, self.manager.grid_manager.grid.get_step(
        )

    def call_set_grid_show(self) -> int:
        return self.call_set_grid()[0]

    def call_set_grid_size(self) -> int:
        return self.call_set_grid()[1]

    def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
        super().resizeEvent(event)
        self.update()
        x, y = self.manager.grid_manager.zero_point_dot.get_pos()
        x -= self.manager.grid_manager.zero_point_dot.get_zero()[0]
        y -= self.manager.grid_manager.zero_point_dot.get_zero()[1]
        new_x, new_y = event.size().width() // 2, event.size().height() // 2

        [
            widget.move_event(
                widget.x() + new_x -
                self.manager.grid_manager.zero_point_dot.get_zero()[0],
                widget.y() + new_y -
                self.manager.grid_manager.zero_point_dot.get_zero()[1],
                show_pos=False)
            for widget in self.manager.widget_manager.get_all_widgets()
        ]

        self.manager.grid_manager.set_new_zero_point_pos(new_x, new_y)
        self.manager.grid_manager.zero_point_dot.move_event(
            new_x + x, new_y + y)
        self.manager.grid_manager.grid.set_offset_by_zero_point()
        self.manager.grid_manager.grid.generate_grid()
        self.manager.grid_manager.grid.change_core_size(
            event.size().width(),
            event.size().height())
        self.manager.settings_window.set_geometry()
        self.manager.settings_window.update_obj_settings(self)
        self.update()

    def self_menu_show(self):
        """
        main context menu
        """
        pos = self.manager.mouse_manager.get_mouse_pos()
        context_menu = QtWidgets.QMenu()

        context_menu.addAction(
            'Добавить объект',
            lambda: self.manager.widget_manager.add_widget(pos),
            shortcut="Ctrl+N")

        context_menu.setStyleSheet(
            f"font-size: 15px;"
            f"border-radius: 5%;"
            f"border: 1px solid {CONTEXT_MENU_BORDER_COLOR};")

        context_menu.setWindowFlags(context_menu.windowFlags()
                                    | Qt.NoDropShadowWindowHint)
        context_menu.exec_(QtGui.QCursor.pos())

    def arrow_menu_show(self, arrow: Arrow):
        """
        arrow's context menu
        :param arrow: arrow_class.Arrow class
        """
        context_menu = QtWidgets.QMenu()

        context_menu.addAction(
            "Изменить цвет",
            lambda: self.manager.arrow_manager.change_arrow_color(arrow))

        context_menu.addAction(
            'Удалить стрелку',
            lambda: self.manager.arrow_manager.delete_arrow(arrow),
            shortcut=QtCore.Qt.Key_D)

        context_menu.setStyleSheet(f"font-size: 15px;"
                                   f"border-radius: 5%;"
                                   f"border: 1px solid black;")

        context_menu.exec_(QtGui.QCursor.pos())

    def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
        if event.buttons() == QtCore.Qt.LeftButton and self.hasFocus():
            x, y = self.manager.mouse_manager.get_mouse_pos()

            [
                widget.move_event(widget.x() + (event.pos().x() - x),
                                  widget.y() + (event.pos().y() - y),
                                  show_pos=False)
                for widget in self.manager.widget_manager.get_all_widgets()
            ]

            self.manager.grid_manager.zero_point_dot.move_event(
                self.manager.grid_manager.zero_point_dot.x() +
                (event.pos().x() - x),
                self.manager.grid_manager.zero_point_dot.y() +
                (event.pos().y() - y))

            if self.manager.grid_manager.grid.show:
                self.manager.grid_manager.grid.set_offset_by_zero_point()
                self.manager.grid_manager.grid.regenerate_grid()

            self.manager.settings_window.update_obj_settings(self)
            self.update()
        self.manager.mouse_manager.change_mouse_pos(event.x(), event.y())

    def keyReleaseEvent(self, event: QtGui.QKeyEvent) -> None:
        modifier = QtWidgets.QApplication.keyboardModifiers()
        if modifier == Qt.ControlModifier:
            if event.key() in (Qt.Key_N, 1058):

                w = self.manager.widget_manager.add_widget(
                    self.manager.mouse_manager.get_mouse_pos())

                self.update()
                self.manager.widget_manager.clear_focus()
                w.setFocus()
                w.show_angles()
                self.update()
            widget_has_focus = self.manager.widget_manager.widget_has_focus_or_none(
            )
            if widget_has_focus:
                widget_has_focus.keyReleaseEvent(event)
                self.update()
        if not self.hasFocus():
            return
        if event.key() in (QtCore.Qt.Key_R, 1050):
            [
                widget.return_to_fact_pos()
                for widget in self.manager.widget_manager.get_all_widgets()
            ]
            self.manager.grid_manager.zero_point_dot.return_to_zero()
            self.manager.grid_manager.grid.set_offset_by_zero_point()
            self.manager.grid_manager.grid.regenerate_grid()

        if event.key() in (QtCore.Qt.Key_G, 1055):
            self.manager.grid_manager.grid.toggle_show()
            self.manager.settings_window.update_obj_settings(self)
        if event.key() == QtCore.Qt.Key_Plus:
            self.manager.grid_manager.grid.change_step(
                self.manager.grid_manager.grid.get_step() * 2)
            self.manager.grid_manager.grid.set_offset_by_zero_point()
            self.manager.grid_manager.grid.regenerate_grid()
            self.manager.settings_window.update_obj_settings(self)

        elif event.key() == QtCore.Qt.Key_Minus:

            self.manager.grid_manager.grid.change_step(
                self.manager.grid_manager.grid.get_step() // 2)

            self.manager.grid_manager.grid.set_offset_by_zero_point()
            self.manager.grid_manager.grid.regenerate_grid()
            self.manager.settings_window.update_obj_settings(self)
        self.update()

    def mouseReleaseEvent(self, event: QtGui.QMouseEvent) -> None:
        [a.clear_focus() for a in self.manager.arrow_manager.get_all_arrows()]
        if event.button() == QtCore.Qt.RightButton:
            if self.manager.arrow_manager.get_active_arrow():

                self.manager.arrow_manager.delete_arrow(
                    self.manager.arrow_manager.get_active_arrow())

                self.manager.arrow_manager.toggle_active_arrow()
                return
            for arrow in self.manager.arrow_manager.get_all_arrows():
                if arrow.start_pos and arrow.end_pos:
                    x1, y1 = arrow.start_pos
                    x2, y2 = arrow.end_pos
                    x3, y3 = event.pos().x(), event.pos().y()
                    if -3 < check_on_arrow(x1, y1, x2, y2, x3, y3) < 3:
                        self.arrow_menu_show(arrow)
                        self.update()
                        return
            if self.hasFocus():
                self.self_menu_show()
        elif event.button() == QtCore.Qt.LeftButton:
            for arrow in self.manager.arrow_manager.get_all_arrows():
                if arrow.start_pos and arrow.end_pos:
                    x1, y1 = arrow.start_pos
                    x2, y2 = arrow.end_pos
                    x3, y3 = event.pos().x(), event.pos().y()
                    if -3 < check_on_arrow(x1, y1, x2, y2, x3, y3) < 3:
                        arrow.set_focus()
                        self.update()
                        return
            self.manager.settings_window.hide_all_sett()
            self.manager.settings_window.show_sett(self)

            self.manager.arrow_manager.clear_focus_arrows()
        self.manager.widget_manager.clear_focus()
        self.setFocus()
        self.update()

    def dragEnterEvent(self, event: QtGui.QDragEnterEvent) -> None:
        x, y = event.pos().x() - event.source().pos().x(), event.pos().y(
        ) - event.source().pos().y()

        if not self.manager.widget_manager.dragged_obj and \
                event.source().size().width() - event.source().OFFSET - 5 \
                <= x <= \
                event.source().size().width() + 5 and \
                event.source().size().height() - event.source().OFFSET - 5 \
                <= y <= \
                event.source().size().height() + 5:

            self.manager.widget_manager.set_dor(RESIZE)
            event.source().show_size_or_pos_label()
            event.source().show_angles()
            self.manager.settings_window.hide_all_sett()
            self.manager.settings_window.show_sett(event.source())
        else:
            if self.manager.widget_manager.dragged_obj is None:
                self.manager.widget_manager.dragged_obj = event.source()
                self.manager.widget_manager.set_dor(DRAG)
                event.source().show_size_or_pos_label()
                event.source().show_angles()

                self.manager.widget_manager.drag_dot = (event.pos().x() -
                                                        event.source().x(),
                                                        event.pos().y() -
                                                        event.source().y())

                self.manager.settings_window.hide_all_sett()
                self.manager.settings_window.show_sett(event.source())
        event.accept()
        self.update()

    def dragMoveEvent(self, event: QtGui.QDragMoveEvent) -> None:
        obj: TextWidget = event.source()
        modifier_pressed = QtWidgets.QApplication.keyboardModifiers()
        shift_pressed = (int(modifier_pressed)
                         & QtCore.Qt.ShiftModifier) == QtCore.Qt.ShiftModifier
        if self.manager.widget_manager.get_dor() == DRAG:

            obj.move(event.pos().x() - self.manager.widget_manager.drag_dot[0],
                     event.pos().y() - self.manager.widget_manager.drag_dot[1])

            x, y, _, _, x_mod, y_mod, widgets = self.manager.widget_manager.drag_magnet_checker(
                obj)
            if shift_pressed:
                if not x_mod:

                    x = x - (x - self.manager.grid_manager.zero_point_dot.get_pos()[0]) \
                        % (OFFSET_MAGNET * 2)

                if not y_mod:

                    y = y - (y - self.manager.grid_manager.zero_point_dot.get_pos()[1]) \
                        % (OFFSET_MAGNET * 2)

            x, y = max(x, 0), max(y, 0)
            if self.manager.grid_manager.grid.show:

                x, y, widgets = \
                    self.manager.grid_manager.check_and_set_grid_magnet_lines_for_resizing(
                         obj, x, y, x_mod, y_mod, widgets
                    )

            self.manager.widget_manager.set_coords_on_widgets(
                widgets, event, x, y)
            obj.move_event(x, y)
            obj.update_arrows()
        elif self.manager.widget_manager.get_dor() == RESIZE:

            obj_x1, obj_y1, obj_x2, obj_y2, x_mod, y_mod, widgets = \
                self.manager.widget_manager.resize_magnet_checker(obj, event.pos())

            x, y = obj_x2 - obj_x1, obj_y2 - obj_y1
            if shift_pressed:
                if not x_mod:
                    x = max(x - x % (OFFSET_MAGNET * 2), 0)
                if not y_mod:
                    y = max(y - y % (OFFSET_MAGNET * 2), 0)
            self.manager.widget_manager.set_coords_on_widgets(
                widgets, event, x, y)
            obj.resize_event(x, y)

        self.update()

    def dropEvent(self, event: QtGui.QDropEvent) -> None:
        self.manager.widget_manager.dragged_obj = None
        self.manager.grid_manager.drop_magnet_lines()
        self.manager.grid_manager.grid.clear_special_lines()
        event.accept()
        self.manager.widget_manager.set_dor(NONE)
        [
            widget.hide_size_or_pos_label()
            for widget in self.manager.widget_manager.get_all_widgets()
        ]
        self.update()

    def paintEvent(self, event: QtGui.QPaintEvent) -> None:
        self.qp.begin(self)
        self.qp.setRenderHint(QPainter.Antialiasing)
        self.manager.grid_manager.grid.draw(self.qp)
        for arrow in self.manager.arrow_manager.get_all_arrows():
            self.qp.setPen(QPen(QColor(arrow.get_color()), 2))
            end = self.manager.mouse_manager.get_mouse_pos()
            if arrow.draw(self.qp, end_pos=end):
                self.update()
        pen = QPen(QColor(MAGNET_LINE_COLOR), 1)
        pen.setStyle(QtCore.Qt.DashLine)
        self.qp.setPen(pen)
        mls = self.manager.grid_manager.get_magnet_lines()
        if mls:
            self.qp.drawLines(*mls)
        self.qp.end()