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


Posted in Python onApril 20, 2018

本文通过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_()

运行结果:

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

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

Python 相关文章推荐
50行代码实现贪吃蛇(具体思路及代码)
Apr 27 Python
windows下ipython的安装与使用详解
Oct 20 Python
Python正则表达式经典入门教程
May 22 Python
Python实现的桶排序算法示例
Nov 29 Python
tensorflow实现简单的卷积网络
May 24 Python
Python比较配置文件的方法实例详解
Jun 06 Python
Python3+Appium实现多台移动设备操作的方法
Jul 05 Python
python字符串分割及字符串的一些常规方法
Jul 24 Python
MATLAB数学建模之画图汇总
Jul 16 Python
简单了解python关键字global nonlocal区别
Sep 21 Python
python matlab库简单用法讲解
Dec 31 Python
Python list去重且保持原顺序不变的方法
Apr 03 Python
Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作
Apr 20 #Python
python3+PyQt5实现支持多线程的页面索引器应用程序
Apr 20 #Python
python3+PyQt5+Qt Designer实现扩展对话框
Apr 20 #Python
pandas获取groupby分组里最大值所在的行方法
Apr 20 #Python
pandas多级分组实现排序的方法
Apr 20 #Python
Python PyQt4实现QQ抽屉效果
Apr 20 #Python
Python在groupby分组后提取指定位置记录方法
Apr 20 #Python
You might like
一个简易需要注册的留言版程序
2006/10/09 PHP
PHP中设置时区,记录日志文件的实现代码
2013/01/07 PHP
js通过地址栏给action传值(中文乱码全是问号)
2013/05/02 Javascript
js 针对html DOM元素操作等经验累积
2014/03/11 Javascript
JS实现两表格里数据来回转移的方法
2015/05/28 Javascript
javascript编写贪吃蛇游戏
2015/07/07 Javascript
理解JavaScript中worker事件api
2015/12/25 Javascript
AngularJS中的Directive自定义一个表格
2016/01/25 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
2016/09/04 Javascript
浅谈js的异步执行
2016/10/18 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
element-ui中的select下拉列表设置默认值方法
2018/08/24 Javascript
Python深入学习之内存管理
2014/08/31 Python
Python从文件中读取数据的方法讲解
2019/02/14 Python
PYQT5实现控制台显示功能的方法
2019/06/25 Python
Python将列表中的元素转化为数字并排序的示例
2019/12/25 Python
在flask中使用python-dotenv+flask-cli自定义命令(推荐)
2020/01/05 Python
自定义Django默认的sitemap站点地图样式
2020/03/04 Python
django admin后管定制-显示字段的实例
2020/03/11 Python
python实现输入三角形边长自动作图求面积案例
2020/04/12 Python
手把手教你将Flask应用封装成Docker服务的实现
2020/08/19 Python
如何在vscode中安装python库的方法步骤
2021/01/06 Python
使用Canvas操作像素的方法
2018/06/14 HTML / CSS
世界上最大的街头服饰网站:Karmaloop
2017/02/04 全球购物
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
春季运动会广播稿大全
2014/02/19 职场文书
导游个人求职信
2014/04/25 职场文书
电子商务求职信
2014/06/15 职场文书
我们的节日国庆活动方案
2014/08/19 职场文书
2014年环境卫生工作总结
2014/11/24 职场文书
合理化建议书
2015/02/04 职场文书
无锡灵山大佛导游词
2015/02/09 职场文书
Python控制台输出俄罗斯方块移动和旋转功能
2021/04/18 Python
基于Python编写简易版的天天跑酷游戏的示例代码
2022/03/23 Python
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL