Python3使用PyQt5制作简单的画板/手写板实例

1.前言

版本:Python3.6.1 + PyQt5

写一个程序的时候需要用到画板/手写板,只需要最简单的那种。原以为网上到处都是,结果找了好几天,都没有找到想要的结果。

网上的要么是非python版的qt程序(要知道qt版本之间差异巨大,还是非同一语言的),改写难度太大。要么是PyQt4的老程序,很多都已经不能在PyQt5上运行了。要么是大神写的特别复杂的程序,简直是直接做出了一个Windows自带的画图版,只能膜拜~

于是我只能在众多代码中慢慢寻找自己需要的那一小部分,然后不断地拼凑,不断地理解大神的代码,最终做出这么一个简单的画板。望着这个简单的画板我真是泪流满面,中间数十次拼不对拼不全导致程序无数次崩溃,差点就放弃了......

2.简单的画板1.0

在简单的画板1.0这里,实现的功能是:在定点和移动中的鼠标所在处画一条线

如图所示:

鼠标按住移动的话,线也会跟着移动,从这个简单的程序开始理解PyQt5的运行机制吧。

'''

简单的画板1.0

功能:在定点和移动中的鼠标所在处画一条线

作者:PyLearn

最后修改日期: 2017/10/18

'''

import sys

from PyQt5.QtWidgets import (QApplication, QWidget)

from PyQt5.QtGui import (QPainter, QPen)

from PyQt5.QtCore import Qt

class Example(QWidget):

def __init__(self):

super(Example, self).__init__()

#resize设置宽高,move设置位置

self.resize(400, 300)

self.move(100, 100)

self.setWindowTitle("简单的画板1.0")

#setMouseTracking设置为False,否则不按下鼠标时也会跟踪鼠标事件

self.setMouseTracking(False)

#设置两个变量接收移动中的点的x、y坐标

self.pos_x = 20

self.pos_y = 20

def paintEvent(self, event):

painter = QPainter()

painter.begin(self)

pen = QPen(Qt.black, 2, Qt.SolidLine)

painter.setPen(pen)

#定点(20, 20) 到 (self.pos_x, self.pos_y)之间画线

painter.drawLine(20, 20, self.pos_x, self.pos_y)

painter.end()

def mouseMoveEvent(self, event):

'''

按住鼠标移动事件:更新pos_x和pos_y的值

调用update()函数在这里相当于调用paintEvent()函数

每次update()时,之前调用的paintEvent()留下的痕迹都会清空

'''

self.pos_x = event.pos().x()

self.pos_y = event.pos().y()

self.update()

if __name__ == "__main__":

app = QApplication(sys.argv)

pyqt_learn = Example()

pyqt_learn.show()

app.exec_()

3.简单的画板2.0

从以上的简单的画板1.0程序的运行可以发现,按住鼠标移动的时候,线也会跟着移动,那如何让之前的线留下痕迹,而不是消失呢?

在简单的画板2.0中,使用一个列表保存所有移动过的点,然后要画线的时候,循环遍历列表,依次画出列表中点到定点之间的线即可。

效果如图所示:

'''

简单的画板2.0

功能:

在定点和移动中的鼠标所在处画一条线

并将画过的线都保留在窗体上

作者:PyLearn

最后修改日期: 2017/10/18

'''

import sys

from PyQt5.QtWidgets import (QApplication, QWidget)

from PyQt5.QtGui import (QPainter, QPen)

from PyQt5.QtCore import Qt

class Example(QWidget):

def __init__(self):

super(Example, self).__init__()

#resize设置宽高,move设置位置

self.resize(400, 300)

self.move(100, 100)

self.setWindowTitle("简单的画板2.0")

#setMouseTracking设置为False,否则不按下鼠标时也会跟踪鼠标事件

self.setMouseTracking(False)

'''

要想将画过的线都保留在窗体上

需要一个列表来保存所有移动过的点

'''

self.pos_xy = []

def paintEvent(self, event):

painter = QPainter()

painter.begin(self)

pen = QPen(Qt.black, 2, Qt.SolidLine)

painter.setPen(pen)

#循环遍历self.pos_xy中每个点,然后画点到定点之间的线

for pos_tmp in self.pos_xy:

painter.drawLine(20, 20, pos_tmp[0], pos_tmp[1])

painter.end()

def mouseMoveEvent(self, event):

'''

按住鼠标移动事件:将当前点添加到pos_xy列表中

调用update()函数在这里相当于调用paintEvent()函数

每次update()时,之前调用的paintEvent()留下的痕迹都会清空

'''

#中间变量pos_tmp提取当前点

pos_tmp = (event.pos().x(), event.pos().y())

#pos_tmp添加到self.pos_xy中

self.pos_xy.append(pos_tmp)

self.update()

if __name__ == "__main__":

app = QApplication(sys.argv)

pyqt_learn = Example()

pyqt_learn.show()

app.exec_()

4.简单的画板3.0

好了,接下来进入正题了。简单的画板2.0不过是画鼠标所在点到定点的线,那么如何将按住鼠标后移动的轨迹保留在窗体上?

这个就需要一个列表来保存所有移动过的点,然后把所有相邻两个点之间都画一条线,就能断断续续连成鼠标的痕迹了。

效果如图所示:

是不是就画出鼠标移动的轨迹了!

不过这也是有缺点的,比如说写个5看看:

硬生生变成了一个5不是5, 6不是6的数字。这是因为再次提笔画时,5上面的那一横跟之前画的尾巴那里连起来了。好好想想,这个问题怎么解决呢?

'''

简单的画板3.0

功能:将按住鼠标后移动的轨迹保留在窗体上

作者:PyLearn

最后修改日期: 2017/10/18

'''

import sys

from PyQt5.QtWidgets import (QApplication, QWidget)

from PyQt5.QtGui import (QPainter, QPen)

from PyQt5.QtCore import Qt

class Example(QWidget):

def __init__(self):

super(Example, self).__init__()

#resize设置宽高,move设置位置

self.resize(400, 300)

self.move(100, 100)

self.setWindowTitle("简单的画板3.0")

#setMouseTracking设置为False,否则不按下鼠标时也会跟踪鼠标事件

self.setMouseTracking(False)

'''

要想将按住鼠标后移动的轨迹保留在窗体上

需要一个列表来保存所有移动过的点

'''

self.pos_xy = []

def paintEvent(self, event):

painter = QPainter()

painter.begin(self)

pen = QPen(Qt.black, 2, Qt.SolidLine)

painter.setPen(pen)

'''

首先判断pos_xy列表中是不是至少有两个点了

然后将pos_xy中第一个点赋值给point_start

利用中间变量pos_tmp遍历整个pos_xy列表

point_end = pos_tmp

画point_start到point_end之间的线

point_start = point_end

这样,不断地将相邻两个点之间画线,就能留下鼠标移动轨迹了

'''

if len(self.pos_xy) > 1:

point_start = self.pos_xy[0]

for pos_tmp in self.pos_xy:

point_end = pos_tmp

painter.drawLine(point_start[0], point_start[1], point_end[0], point_end[1])

point_start = point_end

painter.end()

def mouseMoveEvent(self, event):

'''

按住鼠标移动事件:将当前点添加到pos_xy列表中

调用update()函数在这里相当于调用paintEvent()函数

每次update()时,之前调用的paintEvent()留下的痕迹都会清空

'''

#中间变量pos_tmp提取当前点

pos_tmp = (event.pos().x(), event.pos().y())

#pos_tmp添加到self.pos_xy中

self.pos_xy.append(pos_tmp)

self.update()

if __name__ == "__main__":

app = QApplication(sys.argv)

pyqt_learn = Example()

pyqt_learn.show()

app.exec_()

5.简单的画板4.0

简单的画板3.0中有一个致命的问题,那就是连续的问题,比如说要写一个三位数123:

很难看对不对?

解决这个问题的方法应该是有很多种的,我也没有深入想,就直接用了这个麻烦点的方法。

我的办法是当鼠标按住移动然后松开的时候,往保存所有移动过的点的列表中添加一个断点(-1, -1)。然后在每次画线的时候,都判断一下是不是断点,如果是断点的话就想办法跳过去,并且不连续的开始接着画线。

效果如图所示:

以下是具体实现代码:

'''

简单的画板4.0

功能:

将按住鼠标后移动的轨迹保留在窗体上

并解决二次作画时与上次痕迹连续的问题

作者:PyLearn

最后修改日期: 2017/10/18

'''

import sys

from PyQt5.QtWidgets import (QApplication, QWidget)

from PyQt5.QtGui import (QPainter, QPen)

from PyQt5.QtCore import Qt

class Example(QWidget):

def __init__(self):

super(Example, self).__init__()

#resize设置宽高,move设置位置

self.resize(400, 300)

self.move(100, 100)

self.setWindowTitle("简单的画板4.0")

#setMouseTracking设置为False,否则不按下鼠标时也会跟踪鼠标事件

self.setMouseTracking(False)

'''

要想将按住鼠标后移动的轨迹保留在窗体上

需要一个列表来保存所有移动过的点

'''

self.pos_xy = []

def paintEvent(self, event):

painter = QPainter()

painter.begin(self)

pen = QPen(Qt.black, 2, Qt.SolidLine)

painter.setPen(pen)

'''

首先判断pos_xy列表中是不是至少有两个点了

然后将pos_xy中第一个点赋值给point_start

利用中间变量pos_tmp遍历整个pos_xy列表

point_end = pos_tmp

判断point_end是否是断点,如果是

point_start赋值为断点

continue

判断point_start是否是断点,如果是

point_start赋值为point_end

continue

画point_start到point_end之间的线

point_start = point_end

这样,不断地将相邻两个点之间画线,就能留下鼠标移动轨迹了

'''

if len(self.pos_xy) > 1:

point_start = self.pos_xy[0]

for pos_tmp in self.pos_xy:

point_end = pos_tmp

if point_end == (-1, -1):

point_start = (-1, -1)

continue

if point_start == (-1, -1):

point_start = point_end

continue

painter.drawLine(point_start[0], point_start[1], point_end[0], point_end[1])

point_start = point_end

painter.end()

def mouseMoveEvent(self, event):

'''

按住鼠标移动事件:将当前点添加到pos_xy列表中

调用update()函数在这里相当于调用paintEvent()函数

每次update()时,之前调用的paintEvent()留下的痕迹都会清空

'''

#中间变量pos_tmp提取当前点

pos_tmp = (event.pos().x(), event.pos().y())

#pos_tmp添加到self.pos_xy中

self.pos_xy.append(pos_tmp)

self.update()

def mouseReleaseEvent(self, event):

'''

重写鼠标按住后松开的事件

在每次松开后向pos_xy列表中添加一个断点(-1, -1)

然后在绘画时判断一下是不是断点就行了

是断点的话就跳过去,不与之前的连续

'''

pos_test = (-1, -1)

self.pos_xy.append(pos_test)

self.update()

if __name__ == "__main__":

app = QApplication(sys.argv)

pyqt_learn = Example()

pyqt_learn.show()

app.exec_()

至此,终于完成了简单的画板程序的实现!

另外,如果在使用这个代码的过程中有遇到什么问题,也欢迎向我反馈。

以上这篇Python3使用PyQt5制作简单的画板/手写板实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持码农之家。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

python手写板_Python3使用PyQt5制作简单的画板/手写板的代码详解相关推荐

  1. python手写板_Python3使用PyQt5制作简单的画板/手写板实例

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  2. 用python画画简单代码_Python3使用PyQt5制作简单的画板/手写板实例

    1.前言 版本:Python3.6.1 + PyQt5 写一个程序的时候需要用到画板/手写板,只需要最简单的那种.原以为网上到处都是,结果找了好几天,都没有找到想要的结果. 网上的要么是非python ...

  3. python怎么建立画板_Python3使用PyQt5制作简单的画板/手写板实例

    1.前言 版本:Python3.6.1 + PyQt5 写一个程序的时候需要用到画板/手写板,只需要最简单的那种.原以为网上到处都是,结果找了好几天,都没有找到想要的结果. 网上的要么是非python ...

  4. python实现画板_Python3使用PyQt5制作简单的画板/手写板

    0.目录 1.前言 在定点和移动中的鼠标所在处画一条线 在定点和移动中的鼠标所在处画一条线 并将画过的线都保留在窗体上 将按住鼠标后移动的轨迹保留在窗体上 将按住鼠标后移动的轨迹保留在窗体上 并解决二 ...

  5. 基于python的随机森林回归实现_PYTHON | 随机森林实战(代码+详解)

    大家好,我是菜鸟君,之前跟大家聊过R语言的随机森林建模,指路 R语言 | 随机森林建模实战(代码+详解),作为刚过完1024节日的码农算法工程师来说,怎么可能只会用一种语言呢?今天就来说说Python ...

  6. python的常量和变量_python中的常量和变量代码详解

    局部和全局变量: # name='lhf' # def change_name(): # # global name # name='帅了一比' # print('change_name',name) ...

  7. 【TensorFlow】TFRecord数据集的制作:读取、显示及代码详解

    在跑通了官网的mnist和cifar10数据之后,笔者尝试着制作自己的数据集,并保存,读入,显示. TensorFlow可以支持cifar10的数据格式, 也提供了标准的TFRecord 格式. te ...

  8. Python数据可视化-使用 Pyecharts 制作 Timeline(时间轴组件)详解

    内容介绍 本文介绍基于 Python3 的 Pyecharts 制作 Timeline(时间轴组件) 时需要使用的设置参数和常用模板案例,可根据实际情况对案例中的内容进行调整即可. 使用 Pyecha ...

  9. 对于初学python编程语言的学习者最适合的初级程序教程以及代码详解!!

    一 .首先学习在Python编写代码过程中应当注意的一些问题 #什么是注释-提示程序员或者阅读代码的人,当执行程序的时候 并不会执行注释,代码也不会被注释影响 #为什么要写注释? 团队协同配合,方便自 ...

  10. 用python刷网页浏览量_Python 刷点击量的代码详解

    [Python]代码 import webbrowser as web import re import urllib import time import os def spider(url,url ...

最新文章

  1. Plant Physiol. | 中科院遗传所储成才研究组发现水稻NLR类抗病基因突变导致的白叶枯病感病机制...
  2. 又美又飒!这位985大学小姐姐,堪称今年最强博士后!
  3. JFrame 居中显示
  4. PHP调用JS/CSS方法
  5. Spring AOP在事务中的应用典范
  6. fir fpga 不同截止频率_一种新的FIR滤波器系数量化方法
  7. linux系统挂载磁盘慢,arch开机速度竟然是挂载磁盘拖慢了。。
  8. c语言调用子程序,哪位师傅知道51单片机怎样编写子程序?C语言的。在主程序里调...
  9. xml-apis-ext.jar
  10. windows安装tensorflow GPU
  11. 如何解决“已有打开的与此命令相关联的 DataReader,必须首先将它关闭。”
  12. 设计模式(Design Patterns)总结归纳
  13. 使用免费软件Emu8086学习汇编
  14. 打印机扫描显示计算机故障或繁忙,打印机无法扫描_如何用打印机进行扫描,如何用打印机扫描文件...
  15. 疫情时代无接触AI人脸识别技术助力智慧工地迅猛发展
  16. linux中安装apr
  17. edison\arduino-1.5.3-Intel.1.0.3闪退
  18. android 4.4 沉浸模式,大杀器:安卓4.4沉浸模式强制开启!
  19. 【组合数学 】 推广牛顿二项式 ( 牛顿二项式推广 | 推导流程 | 题目解析 )
  20. 关于Win10电脑连接WIFI时出现 “无法连接到这个网络” 问题的解决方法

热门文章

  1. DNS、HTTP劫持的一些事
  2. 不经艰难困苦,何来玉汝于成
  3. 监测 Windows 应用行为
  4. 经典指标:SAR算法和应用
  5. ENSP未找到base device,是否立即注册
  6. 钢铁骑士团服务器端文件,《钢铁骑士团》新手必读 游戏道具介绍
  7. 如何删除word页眉的横线
  8. ME909 ECM拨号上网总结
  9. 2018——走过的路
  10. Shi-Tomasi特征点(角点)检测及追踪方法