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实现ftp客户端示例分享
Feb 17 Python
Python使用新浪微博API发送微博的例子
Apr 10 Python
在Python中操作时间之strptime()方法的使用
Dec 30 Python
Python温度转换实例分析
Jan 17 Python
Django REST framework 如何实现内置访问频率控制
Jul 23 Python
python函数参数(必须参数、可变参数、关键字参数)
Aug 16 Python
pycharm通过anaconda安装pyqt5的教程
Mar 24 Python
Django调用支付宝接口代码实例详解
Apr 04 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
python同时遍历两个list用法说明
May 02 Python
8g内存用python读取10文件_面试题-python 如何读取一个大于 10G 的txt文件?
May 28 Python
自动在Windows中运行Python脚本并定时触发功能实现
Sep 04 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批量删除数据
2007/01/18 PHP
深入PHP nl2br()格式化输出的详解
2013/06/05 PHP
PHP遍历目录并返回统计目录大小
2014/06/09 PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
2016/03/10 PHP
PHP strip_tags保留多个HTML标签的方法
2016/05/22 PHP
php文件系统处理方法小结
2016/05/23 PHP
在b/s开发中经常用到的javaScript技术
2006/08/23 Javascript
JavaScript 拖拉缩放效果
2008/12/10 Javascript
防止动态加载JavaScript引起的内存泄漏问题
2009/10/08 Javascript
js操纵dom生成下拉列表框的方法
2014/02/24 Javascript
javascript正则表达式定义(语法)总结
2016/01/08 Javascript
js根据手机客户端浏览器类型,判断跳转官网/手机网站多个实例代码
2016/04/30 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
angularjs 获取默认选中的单选按钮的value方法
2018/02/28 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
2019/05/27 Javascript
vue+koa2实现session、token登陆状态验证的示例
2019/08/30 Javascript
浅谈Vue SSR中的Bundle的具有使用
2019/11/21 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
Python聚类算法之DBSACN实例分析
2015/11/20 Python
Python语言描述最大连续子序列和
2017/12/05 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
基于python 将列表作为参数传入函数时的测试与理解
2020/06/05 Python
Expedia英国:全球最大的在线旅游公司
2017/09/07 全球购物
俄罗斯韩国化妆品网上商店:Cosmasi.ru
2019/10/31 全球购物
什么是Deployment descriptors;都有什么类型的部署描述符
2015/07/28 面试题
急诊科护士自我鉴定
2013/10/14 职场文书
四年大学生活的个人自我评价
2013/12/11 职场文书
行政人事经理职位说明书
2014/03/05 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
合作协议书格式
2014/08/19 职场文书
党员对照检查材料思想汇报
2014/09/16 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
酒店工程部岗位职责
2015/02/12 职场文书
大学生实习证明
2015/06/16 职场文书
小学信息技术教学反思
2016/02/16 职场文书
python自动化测试之Selenium详解
2022/03/13 Python