python3+PyQt5实现自定义窗口部件Counters
作者:basisworker 发布时间:2021-05-21 10:47:47
标签:python3,PyQt5,窗口
本文通过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_()
运行结果:
来源:https://blog.csdn.net/xiaoyangyang20/article/details/55803064


猜你喜欢
- 我希望大家敲一遍<!DOCTYPE html><html><head><meta charset=
- 本文实例为大家分享了JavaScript/jQuery实现切换页面效果的具体代码,供大家参考,具体内容如下<!DOCTYPE html
- 1. 事务介绍MVCC之前,先介绍下事务:事务是为了保证数据库中数据的完整性和一致性。事务的4个基本要素:原子性(Atomicity):要么
- 1.生成日志并通过http传输出去(通过HTTPHandler方式):#生成并发送日志import loggingfrom logging.
- 本文实例讲述了python求pi的方法,是一篇翻译自国外网站的文章,分享给大家供大家参考。具体实现方法如下:#_*_ coding=utf-
- 在Mysql 中删除数据以及数据表非常的容易,但是需要特别小心,因为一旦删除所有数据都会消失。删除数据删除表内数据,使用delete关键字。
- 程序是从上到下顺序执行的,同时可以通过一些控制语句来改变执行的路线,受控制语句影响下,程序最终的执行路线就是控制流。js 里面的控制语句有
- 零、配置Tomcat默认情况下Tomcat是没有配置用户角色权限的但是,后续Jenkins部署项目到Tomcat服务器,需要用到Tomcat
- 代码如下:Class template Private c_Char, c_Path, c
- 本文实例讲述了python实现写日志封装类。分享给大家供大家参考。具体如下:# encoding:utf-8import sysimport
- 很久之前,分享过一次Python代码实现验证码识别的办法。当时采用的是pillow+pytesseract,优点是免费,较为易用。但其识别精
- 尾递归是一种特殊的递归形式,它在递归调用时不会产生新的栈帧,从而避免了栈溢出的问题。Python并没有对尾递归进行优化,但我们可以通过一些技
- 一、背景最近有个需求是从一个后台的留言网站爬取留言数据,后台管理网站必然涉及到了登录,登录就有个验证码的问题必须得解决,由于验证码是从后端生
- 前2种方法主要用到了列表解析,性能稍差,而最后一种使用的时候生成器表达式,相比列表解析,更省内存列表解析和生成器表达式很相似:列表解析[ex
- 最近项目用到了bootstrap框架,其中前端用的校验,采用的是bootstrapvalidator插件,也是非常强大的一款插件。我这里用的
- 最新的支持IE、firefox、chrome有提示信息的代码:<script type="text/javascript&q
- 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往
- 概述在我们使用内置打印函数print时,打印出的Python数据结构对象总是一行的输出的方式,这样对数据结构较复杂或数据较多的对象的显示并不
- 项目场景:Python项目需要画两组数据的双柱状图,以下以一周七天两位小朋友吃糖颗数为例进行演示,用matplotlib库实现代码:impo
- 先说迭代器,对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用it