Пример #1
0
 def paintEvent(self, e):
     """ Draw the border. """
     if self.drawBorder:
         p = QPainter(self)
         if self.roundCorners:
             # draw quarter-circles for borders
             p.drawArc(0, 0, self.cornerRadius, self.cornerRadius, 1440, 1440)
             p.drawArc(0, self.height() - self.cornerRadius,
                       self.cornerRadius, self.cornerRadius, 2880, 1440)
             p.drawArc(self.width() - self.cornerRadius,
                       self.height() - self.cornerRadius,
                       self.cornerRadius, self.cornerRadius, 4320, 1440)
             p.drawArc(self.width() - self.cornerRadius,
                       0, self.cornerRadius, self.cornerRadius, 5760, 1440)
             corner = self.cornerRadius / 2
             p.drawLine(corner, 0, self.width() - corner, 0)
             p.drawLine(0, corner, 0, self.height() - corner)
             p.drawLine(corner, self.height()-1,
                        self.width() - corner, self.height()-1)
             p.drawLine(self.width()-1, corner, self.width()-1,
                        self.height() - corner)
         else:
             p.drawRect(0, 0, self.width(), self.height())
     QWidget.paintEvent(self, e)
Пример #2
0
class BoardWidget(QWidget):
    CHECKER_SIZE_TO_FIELD = 0.6
    BORDER_SIZE_TO_FIELD = 0.5

    field_clicked = Signal(int, int, int)   # button, x, y

    def __init__(self, board, parent=None):
        super(BoardWidget, self).__init__(parent)
        self.board = board

        self._selected_field = None     # (x_field, y_field) or None
        self._available_moves = []      # [(x_field, y_field), ...] or None
        self._painter = QPainter()

        self._background_brush = QBrush(Qt.gray)
        self._white_field_brush = QBrush(Qt.white)
        self._black_field_brush = QBrush(Qt.black)
        self._white_checker_brush = QBrush(Qt.white)
        self._white_king_checker_brush = QBrush(Qt.white)
        self._selected_field_brush = QBrush(Qt.blue)
        self._available_move_field_brush = QBrush(Qt.green)
        self._black_checker_brush = QBrush(Qt.black)
        self._black_king_checker_brush = QBrush(Qt.black)
        self._white_checker_pen = QPen(QBrush(Qt.gray), 5, j=Qt.RoundJoin)
        self._black_checker_pen = QPen(QBrush(Qt.gray), 5, j=Qt.RoundJoin)
        self._white_king_checker_pen = QPen(QBrush(Qt.red), 5, j=Qt.RoundJoin)
        self._black_king_checker_pen = QPen(QBrush(Qt.red), 5, j=Qt.RoundJoin)
        self._border_brush = QBrush(QColor.fromRgb(205, 127, 50))

        self._field_size = None
        self._border_size = None

    def set_selected_field(self, field):
        assert field is None or len(field) == 2

        self._selected_field = field

    def set_available_moves(self, fields):
        assert all(len(field) == 2 for field in fields) or fields is None

        if not fields:
            self._available_moves = []

        self._available_moves = fields

    def board_rect(self):
        rect = self.rect()
        size = min([rect.width(), rect.height()]) - self._border_size * 2
        return QRectF(self._border_size, self._border_size, size, size)

    def field_rect(self, x_field, y_field):
        return QRectF(self._border_size + x_field * self._field_size,
                      self._border_size + (self.board.SIZE - 1 - y_field) * self._field_size,
                      self._field_size, self._field_size)

    def get_field_by_point(self, point):
        x_field = (point.x() - self._border_size) / self._field_size
        y_field = self.board.SIZE - (point.y() - self._border_size) / self._field_size

        if 0 <= x_field < self.board.SIZE and 0 <= y_field < self.board.SIZE:
            return int(x_field), int(y_field)

        return None

    def resizeEvent(self, event):
        rect = self.rect()
        outer_size = min([rect.width(), rect.height()])
        self._field_size = outer_size / float(self.board.SIZE + 2 * self.BORDER_SIZE_TO_FIELD)
        self._border_size = self._field_size * self.BORDER_SIZE_TO_FIELD

    def mousePressEvent(self, event):
        clicked_field = self.get_field_by_point(event.pos())
        if clicked_field:
            self.field_clicked.emit(int(event.button()), clicked_field[0], clicked_field[1])
        return super(BoardWidget, self).mousePressEvent(event)

    def paintEvent(self, event):
        self._painter.begin(self)

        self.draw_background()
        self.draw_border()
        self.draw_fields()
        self.draw_checkers()

        self._painter.end()

    def draw_background(self):
        self._painter.fillRect(self.rect(), self._background_brush)

    def draw_border(self):
        rect = self.rect()
        outer_size = min([rect.width(), rect.height()])
        outer_rect = QRectF(0, 0, outer_size, outer_size)
        inner_rect = self.board_rect()
        self._painter.fillRect(outer_rect, self._border_brush)

        self._painter.setPen(QPen(QBrush(Qt.black), 3))
        self._painter.drawRect(inner_rect)

        labels = 'ABCDEFGHIJ'
        for i in xrange(self.board.SIZE):
            # bottom labels
            left = self._border_size + i * self._field_size
            top = outer_rect.bottom() - self._border_size
            text_rect = QRectF(left, top, self._field_size, self._border_size)
            self._painter.drawText(text_rect, Qt.AlignCenter, labels[i])

            # left labels
            top = self._border_size + (self.board.SIZE - i - 1) * self._field_size
            text_rect = QRectF(0, top, self._border_size, self._field_size)
            self._painter.drawText(text_rect, Qt.AlignCenter, str(i + 1))

    def draw_fields(self):
        for x_field in xrange(self.board.SIZE):
            for y_field in xrange(self.board.SIZE):
                if (x_field, y_field) == self._selected_field:
                    brush = self._selected_field_brush
                elif (x_field, y_field) in self._available_moves:
                    brush = self._available_move_field_brush
                elif self.board.is_black_field(x_field, y_field):
                    brush = self._black_field_brush
                else:
                    brush = self._white_field_brush
                self.draw_field(x_field, y_field, brush)

    def draw_field(self, x_field, y_field, brush):
        self._painter.fillRect(self.field_rect(x_field, y_field), brush)

    def draw_checkers(self):
        for checker in self.board.checkers:
            if checker.color == Checker.BLACK:
                if checker.is_king:
                    brush = self._black_king_checker_brush
                    pen = self._black_king_checker_pen
                else:
                    brush = self._black_checker_brush
                    pen = self._black_checker_pen
            else:
                if checker.is_king:
                    brush = self._white_king_checker_brush
                    pen = self._white_king_checker_pen
                else:
                    brush = self._white_checker_brush
                    pen = self._white_checker_pen

            self._painter.setBrush(brush)
            self._painter.setPen(pen)
            field_rect = self.field_rect(checker.x, checker.y)
            radius = self._field_size / 2.0 * self.CHECKER_SIZE_TO_FIELD
            self._painter.drawEllipse(field_rect.center(), radius, radius)