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

来源:互联网 发布:历史api数据后原油波动 编辑:程序博客网 时间:2024/05/22 09:41

本文通过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 python3from PyQt5.QtCore import (QRectF, QSize, Qt)from PyQt5.QtWidgets import (QApplication, QSizePolicy,QWidget)from PyQt5.QtGui import QPainter,QPenBLANK, 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 python3from PyQt5.QtCore import (QRectF, QSize, Qt)from PyQt5.QtWidgets import (QApplication, QSizePolicy,QWidget)from PyQt5.QtGui import QPainter,QPen,QPixmap,QCursorBLANK, 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 0