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 相关文章推荐
用Python代码来绘制彭罗斯点阵的教程
Apr 03 Python
Python爬虫实例爬取网站搞笑段子
Nov 08 Python
Python中optparser库用法实例详解
Jan 26 Python
Python unittest模块用法实例分析
May 25 Python
Python使用numpy模块创建数组操作示例
Jun 20 Python
Python图片转换成矩阵,矩阵数据转换成图片的实例
Jul 02 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
Dec 05 Python
使用python实现抓取腾讯视频所有电影的爬虫
Apr 15 Python
解决python 文本过滤和清理问题
Aug 28 Python
tensorflow 只恢复部分模型参数的实例
Jan 06 Python
tensorflow之读取jpg图像长和宽实例
Jun 18 Python
10个python爬虫入门实例(小结)
Nov 01 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
PHP中使用数组指针函数操作数组示例
2014/11/19 PHP
php使用sql server验证连接数据库的方法
2014/12/25 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
PHP中仿制 ecshop验证码实例
2017/01/06 PHP
PHP闭包定义与使用简单示例
2018/04/13 PHP
jQuery处理xml格式的返回数据(实例解析)
2013/11/28 Javascript
Express.JS使用详解
2014/07/17 Javascript
jQuery语法小结(超实用)
2015/12/31 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
用JS实现轮播图效果(二)
2016/06/26 Javascript
JS实现给对象动态添加属性的方法
2017/01/05 Javascript
node.js 中间件express-session使用详解
2017/05/20 Javascript
JavaScript实现省市联动过程中bug的解决方法
2017/12/04 Javascript
js实现控制文件拖拽并获取拖拽内容功能
2018/02/17 Javascript
node的process以及child_process模块学习笔记
2018/03/06 Javascript
Vue项目中使用better-scroll实现一个轮播图自动播放功能
2018/12/03 Javascript
JavaScript如何借用构造函数继承
2019/11/06 Javascript
JavaScript如何实现监听键盘输入和鼠标监点击
2020/07/20 Javascript
JavaScript经典案例之简易计算器
2020/08/24 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
Django1.3添加app提示模块不存在的解决方法
2014/08/26 Python
python在控制台输出进度条的方法
2015/06/20 Python
Django自定义过滤器定义与用法示例
2018/03/22 Python
浅析Python 3 字符串中的 STR 和 Bytes 有什么区别
2018/10/14 Python
Python3.7实现验证码登录方式代码实例
2020/02/14 Python
Python脚本导出为exe程序的方法
2020/03/25 Python
基于virtualenv创建python虚拟环境过程图解
2020/03/30 Python
用python实现名片管理系统
2020/06/18 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
收藏!10个免费高清视频素材网站!【设计、视频剪辑必备】
2021/03/18 杂记
美国豪华时尚女性精品店:Kirna Zabête
2018/01/11 全球购物
总经理岗位职责
2013/11/09 职场文书
煤矿班组长岗位职责
2013/12/29 职场文书
竞选班干部的演讲稿
2014/04/24 职场文书
大学生工作求职信
2014/06/23 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书