python3+PyQt5 实现自定义窗口部件--Counters自定窗口部件

24 篇文章 0 订阅

本文通过Python3+PyQt5实现自定义部件–Counters自定 窗口部件。这个窗口是3*3的网格。本文有两个例子如下:
/home/yrd/eric_workspace/chap11/counters.py。
/home/yrd/eric_workspace/chap11/counters_dnd.py
第二个例子在第一个例子的基础上实现能通过鼠标拖拽球到不同的网格中。

/home/yrd/eric_workspace/chap11/counters.py

#!/usr/bin/env python3

from PyQt5.QtCore import (QRectF, QSize, Qt)
from PyQt5.QtWidgets import (QApplication, QSizePolicy,QWidget)
from PyQt5.QtGui import QPainter,QPen

BLANK, RED, YELLOW = range(3)


class CountersWidget(QWidget):

    def __init__(self, parent=None):
        super(CountersWidget, self).__init__(parent)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding))
        self.grid = [[BLANK] * 3 for i in range(3)]
        self.selected = [0, 0]
        self.setMinimumSize(self.minimumSizeHint())


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


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


    def mousePressEvent(self, event):
        xOffset = self.width() / 3
        yOffset = self.height() / 3
        if event.x() < xOffset:
            x = 0
        elif event.x() < 2 * xOffset:
            x = 1
        else:
            x = 2
        if event.y() < yOffset:
            y = 0
        elif event.y() < 2 * yOffset:
            y = 1
        else:
            y = 2
        cell = self.grid[x][y]
        if cell == BLANK:
            cell = RED
        elif cell == RED:
            cell = YELLOW
        else:
            cell = BLANK
        self.grid[x][y] = cell
        self.selected = [x, y]
        self.update()


    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Left:
            self.selected[0] = (2 if self.selected[0] == 0
                                else self.selected[0] - 1)
        elif event.key() == Qt.Key_Right:
            self.selected[0] = (0 if self.selected[0] == 2
                                else self.selected[0] + 1)
        elif event.key() == Qt.Key_Up:
            self.selected[1] = (2 if self.selected[1] == 0
                                else self.selected[1] - 1)
        elif event.key() == Qt.Key_Down:
            self.selected[1] = (0 if self.selected[1] == 2
                                else self.selected[1] + 1)
        elif event.key() == Qt.Key_Space:
            x, y = self.selected
            cell = self.grid[x][y]
            if cell == BLANK:
                cell = RED
            elif cell == RED:
                cell = YELLOW
            else:
                cell = BLANK
            self.grid[x][y] = cell
        self.update()


    def paintEvent(self, event=None):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        xOffset = self.width() / 3
        yOffset = self.height() / 3
        for x in range(3):
            for y in range(3):
                cell = self.grid[x][y]
                rect = (QRectF(x * xOffset, y * yOffset,
                        xOffset, yOffset).adjusted(0.5, 0.5, -0.5, -0.5))
                color = None
                if cell == RED:
                    color = Qt.red
                elif cell == YELLOW:
                    color = Qt.yellow
                if color is not None:
                    painter.save()
                    painter.setPen(Qt.black)
                    painter.setBrush(color)
                    painter.drawEllipse(rect.adjusted(2, 2, -2, -2))
                    painter.restore()
                if [x, y] == self.selected:
                    painter.setPen(QPen(Qt.blue, 3))
                else:
                    painter.setPen(Qt.black)
                painter.drawRect(rect)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    form = CountersWidget()
    form.setWindowTitle("Counters")
    form.show()
    app.exec_()

/home/yrd/eric_workspace/chap11/counters_dnd.py

#!/usr/bin/env python3

from PyQt5.QtCore import (QRectF, QSize, Qt)
from PyQt5.QtWidgets import (QApplication, QSizePolicy,QWidget)
from PyQt5.QtGui import QPainter,QPen,QPixmap,QCursor
BLANK, RED, YELLOW = range(3)


class CountersWidget(QWidget):

    def __init__(self, parent=None):
        super(CountersWidget, self).__init__(parent)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding))
        self.grid = [[BLANK] * 3 for i in range(3)]
        self.selected = [0, 0]
        self.setMinimumSize(self.minimumSizeHint())


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


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


    def _xFromEventX(self, event):
        xOffset = self.width() / 3
        if event.x() < xOffset:
            x = 0
        elif event.x() < 2 * xOffset:
            x = 1
        else:
            x = 2
        return x


    def _yFromEventY(self, event):
        yOffset = self.width() / 3
        if event.y() < yOffset:
            y = 0
        elif event.y() < 2 * yOffset:
            y = 1
        else:
            y = 2
        return y


    def mouseDoubleClickEvent(self, event):
        x = self._xFromEventX(event)
        y = self._yFromEventY(event)
        cell = self.grid[x][y]
        if cell == BLANK:
            cell = RED
        elif cell == RED:
            cell = YELLOW
        else:
            cell = BLANK
        self.grid[x][y] = cell
        self.selected = [x, y]
        self.update()


    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Left:
            self.selected[0] = (2 if self.selected[0] == 0
                                else self.selected[0] - 1)
        elif event.key() == Qt.Key_Right:
            self.selected[0] = (0 if self.selected[0] == 2
                                else self.selected[0] + 1)
        elif event.key() == Qt.Key_Up:
            self.selected[1] = (2 if self.selected[1] == 0
                                else self.selected[1] - 1)
        elif event.key() == Qt.Key_Down:
            self.selected[1] = (0 if self.selected[1] == 2
                                else self.selected[1] + 1)
        elif event.key() == Qt.Key_Space:
            x, y = self.selected
            cell = self.grid[x][y]
            if cell == BLANK:
                cell = RED
            elif cell == RED:
                cell = YELLOW
            else:
                cell = BLANK
            self.grid[x][y] = cell
        self.update()


    def paintEvent(self, event=None):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)
        xOffset = self.width() / 3
        yOffset = self.height() / 3
        for x in range(3):
            for y in range(3):
                cell = self.grid[x][y]
                rect = (QRectF(x * xOffset, y * yOffset,
                        xOffset, yOffset).adjusted(0.5, 0.5, -0.5, -0.5))
                color = None
                if cell == RED:
                    color = Qt.red
                elif cell == YELLOW:
                    color = Qt.yellow
                if color is not None:
                    painter.save()
                    painter.setPen(Qt.black)
                    painter.setBrush(color)
                    painter.drawEllipse(rect.adjusted(2, 2, -2, -2))
                    painter.restore()
                if [x, y] == self.selected:
                    painter.setPen(QPen(Qt.blue, 3))
                else:
                    painter.setPen(Qt.black)
                painter.drawRect(rect)


    def mousePressEvent(self, event):
        self.x = self._xFromEventX(event)
        self.y = self._yFromEventY(event)
        cell = self.grid[self.x][self.y]
        color = Qt.darkGray
        if cell == RED:
            color = Qt.red
        elif cell == YELLOW:
            color = Qt.yellow
        pixmap = QPixmap(12, 12)
        pixmap.fill(color)
        self.setCursor(QCursor(pixmap))


    def mouseReleaseEvent(self, event):
        x = self._xFromEventX(event)
        y = self._yFromEventY(event)
        if self.x != x or self.y != y:
            cell = self.grid[self.x][self.y]
            self.grid[self.x][self.y] = BLANK
            self.grid[x][y] = cell
            self.selected = [x, y]
            self.update()
        self.setCursor(Qt.ArrowCursor)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    form = CountersWidget()
    form.setWindowTitle("Counters")
    form.show()
    app.exec_()

运行结果:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值