本文通过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_()
运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。