最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python3使用PyQt5制作簡單的畫板/手寫板實(shí)例

 更新時(shí)間:2017年10月19日 09:10:21   作者:PyLearn  
下面小編就為大家?guī)硪黄狿ython3使用PyQt5制作簡單的畫板/手寫板實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

1.前言

版本:Python3.6.1 + PyQt5

寫一個(gè)程序的時(shí)候需要用到畫板/手寫板,只需要最簡單的那種。原以為網(wǎng)上到處都是,結(jié)果找了好幾天,都沒有找到想要的結(jié)果。

網(wǎng)上的要么是非python版的qt程序(要知道qt版本之間差異巨大,還是非同一語言的),改寫難度太大。要么是PyQt4的老程序,很多都已經(jīng)不能在PyQt5上運(yùn)行了。要么是大神寫的特別復(fù)雜的程序,簡直是直接做出了一個(gè)Windows自帶的畫圖版,只能膜拜~

于是我只能在眾多代碼中慢慢尋找自己需要的那一小部分,然后不斷地拼湊,不斷地理解大神的代碼,最終做出這么一個(gè)簡單的畫板。望著這個(gè)簡單的畫板我真是淚流滿面,中間數(shù)十次拼不對(duì)拼不全導(dǎo)致程序無數(shù)次崩潰,差點(diǎn)就放棄了......

2.簡單的畫板1.0

在簡單的畫板1.0這里,實(shí)現(xiàn)的功能是:在定點(diǎn)和移動(dòng)中的鼠標(biāo)所在處畫一條線
如圖所示:

鼠標(biāo)按住移動(dòng)的話,線也會(huì)跟著移動(dòng),從這個(gè)簡單的程序開始理解PyQt5的運(yùn)行機(jī)制吧。

'''
 簡單的畫板1.0
 功能:在定點(diǎn)和移動(dòng)中的鼠標(biāo)所在處畫一條線
 作者: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設(shè)置寬高,move設(shè)置位置
  self.resize(400, 300)
  self.move(100, 100)
  self.setWindowTitle("簡單的畫板1.0")

  #setMouseTracking設(shè)置為False,否則不按下鼠標(biāo)時(shí)也會(huì)跟蹤鼠標(biāo)事件
  self.setMouseTracking(False)

  #設(shè)置兩個(gè)變量接收移動(dòng)中的點(diǎn)的x、y坐標(biāo)
  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)

  #定點(diǎn)(20, 20) 到 (self.pos_x, self.pos_y)之間畫線
  painter.drawLine(20, 20, self.pos_x, self.pos_y)

  painter.end()

 def mouseMoveEvent(self, event):
  '''
   按住鼠標(biāo)移動(dòng)事件:更新pos_x和pos_y的值
   調(diào)用update()函數(shù)在這里相當(dāng)于調(diào)用paintEvent()函數(shù)
   每次update()時(shí),之前調(diào)用的paintEvent()留下的痕跡都會(huì)清空
  '''
  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程序的運(yùn)行可以發(fā)現(xiàn),按住鼠標(biāo)移動(dòng)的時(shí)候,線也會(huì)跟著移動(dòng),那如何讓之前的線留下痕跡,而不是消失呢?

在簡單的畫板2.0中,使用一個(gè)列表保存所有移動(dòng)過的點(diǎn),然后要畫線的時(shí)候,循環(huán)遍歷列表,依次畫出列表中點(diǎn)到定點(diǎn)之間的線即可。

效果如圖所示:

'''
 簡單的畫板2.0
 功能:
  在定點(diǎn)和移動(dòng)中的鼠標(biāo)所在處畫一條線
  并將畫過的線都保留在窗體上
 作者: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設(shè)置寬高,move設(shè)置位置
  self.resize(400, 300)
  self.move(100, 100)
  self.setWindowTitle("簡單的畫板2.0")

  #setMouseTracking設(shè)置為False,否則不按下鼠標(biāo)時(shí)也會(huì)跟蹤鼠標(biāo)事件
  self.setMouseTracking(False)

  '''
   要想將畫過的線都保留在窗體上
   需要一個(gè)列表來保存所有移動(dòng)過的點(diǎn)
  '''
  self.pos_xy = []

 def paintEvent(self, event):
  painter = QPainter()
  painter.begin(self)
  pen = QPen(Qt.black, 2, Qt.SolidLine)
  painter.setPen(pen)

  #循環(huán)遍歷self.pos_xy中每個(gè)點(diǎn),然后畫點(diǎn)到定點(diǎn)之間的線
  for pos_tmp in self.pos_xy:
   painter.drawLine(20, 20, pos_tmp[0], pos_tmp[1])

  painter.end()

 def mouseMoveEvent(self, event):
  '''
   按住鼠標(biāo)移動(dòng)事件:將當(dāng)前點(diǎn)添加到pos_xy列表中
   調(diào)用update()函數(shù)在這里相當(dāng)于調(diào)用paintEvent()函數(shù)
   每次update()時(shí),之前調(diào)用的paintEvent()留下的痕跡都會(huì)清空
  '''
  #中間變量pos_tmp提取當(dāng)前點(diǎn)
  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

好了,接下來進(jìn)入正題了。簡單的畫板2.0不過是畫鼠標(biāo)所在點(diǎn)到定點(diǎn)的線,那么如何將按住鼠標(biāo)后移動(dòng)的軌跡保留在窗體上?

這個(gè)就需要一個(gè)列表來保存所有移動(dòng)過的點(diǎn),然后把所有相鄰兩個(gè)點(diǎn)之間都畫一條線,就能斷斷續(xù)續(xù)連成鼠標(biāo)的痕跡了。
效果如圖所示:

是不是就畫出鼠標(biāo)移動(dòng)的軌跡了!

不過這也是有缺點(diǎn)的,比如說寫個(gè)5看看:



硬生生變成了一個(gè)5不是5, 6不是6的數(shù)字。這是因?yàn)樵俅翁峁P畫時(shí),5上面的那一橫跟之前畫的尾巴那里連起來了。好好想想,這個(gè)問題怎么解決呢?

'''
 簡單的畫板3.0
 功能:將按住鼠標(biāo)后移動(dòng)的軌跡保留在窗體上
 作者: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設(shè)置寬高,move設(shè)置位置
  self.resize(400, 300)
  self.move(100, 100)
  self.setWindowTitle("簡單的畫板3.0")

  #setMouseTracking設(shè)置為False,否則不按下鼠標(biāo)時(shí)也會(huì)跟蹤鼠標(biāo)事件
  self.setMouseTracking(False)

  '''
   要想將按住鼠標(biāo)后移動(dòng)的軌跡保留在窗體上
   需要一個(gè)列表來保存所有移動(dòng)過的點(diǎn)
  '''
  self.pos_xy = []

 def paintEvent(self, event):
  painter = QPainter()
  painter.begin(self)
  pen = QPen(Qt.black, 2, Qt.SolidLine)
  painter.setPen(pen)

  '''
   首先判斷pos_xy列表中是不是至少有兩個(gè)點(diǎn)了
   然后將pos_xy中第一個(gè)點(diǎn)賦值給point_start
   利用中間變量pos_tmp遍歷整個(gè)pos_xy列表
    point_end = pos_tmp
    畫point_start到point_end之間的線
    point_start = point_end
   這樣,不斷地將相鄰兩個(gè)點(diǎn)之間畫線,就能留下鼠標(biāo)移動(dòng)軌跡了
  '''
  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):
  '''
   按住鼠標(biāo)移動(dòng)事件:將當(dāng)前點(diǎn)添加到pos_xy列表中
   調(diào)用update()函數(shù)在這里相當(dāng)于調(diào)用paintEvent()函數(shù)
   每次update()時(shí),之前調(diào)用的paintEvent()留下的痕跡都會(huì)清空
  '''
  #中間變量pos_tmp提取當(dāng)前點(diǎn)
  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中有一個(gè)致命的問題,那就是連續(xù)的問題,比如說要寫一個(gè)三位數(shù)123:


很難看對(duì)不對(duì)?

解決這個(gè)問題的方法應(yīng)該是有很多種的,我也沒有深入想,就直接用了這個(gè)麻煩點(diǎn)的方法。

我的辦法是當(dāng)鼠標(biāo)按住移動(dòng)然后松開的時(shí)候,往保存所有移動(dòng)過的點(diǎn)的列表中添加一個(gè)斷點(diǎn)(-1, -1)。然后在每次畫線的時(shí)候,都判斷一下是不是斷點(diǎn),如果是斷點(diǎn)的話就想辦法跳過去,并且不連續(xù)的開始接著畫線。

效果如圖所示:



以下是具體實(shí)現(xiàn)代碼:

'''
 簡單的畫板4.0
 功能:
  將按住鼠標(biāo)后移動(dòng)的軌跡保留在窗體上
  并解決二次作畫時(shí)與上次痕跡連續(xù)的問題
 作者: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設(shè)置寬高,move設(shè)置位置
  self.resize(400, 300)
  self.move(100, 100)
  self.setWindowTitle("簡單的畫板4.0")

  #setMouseTracking設(shè)置為False,否則不按下鼠標(biāo)時(shí)也會(huì)跟蹤鼠標(biāo)事件
  self.setMouseTracking(False)

  '''
   要想將按住鼠標(biāo)后移動(dòng)的軌跡保留在窗體上
   需要一個(gè)列表來保存所有移動(dòng)過的點(diǎn)
  '''
  self.pos_xy = []

 def paintEvent(self, event):
  painter = QPainter()
  painter.begin(self)
  pen = QPen(Qt.black, 2, Qt.SolidLine)
  painter.setPen(pen)

  '''
   首先判斷pos_xy列表中是不是至少有兩個(gè)點(diǎn)了
   然后將pos_xy中第一個(gè)點(diǎn)賦值給point_start
   利用中間變量pos_tmp遍歷整個(gè)pos_xy列表
    point_end = pos_tmp

    判斷point_end是否是斷點(diǎn),如果是
     point_start賦值為斷點(diǎn)
     continue
    判斷point_start是否是斷點(diǎn),如果是
     point_start賦值為point_end
     continue

    畫point_start到point_end之間的線
    point_start = point_end
   這樣,不斷地將相鄰兩個(gè)點(diǎn)之間畫線,就能留下鼠標(biāo)移動(dòng)軌跡了
  '''
  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):
  '''
   按住鼠標(biāo)移動(dòng)事件:將當(dāng)前點(diǎn)添加到pos_xy列表中
   調(diào)用update()函數(shù)在這里相當(dāng)于調(diào)用paintEvent()函數(shù)
   每次update()時(shí),之前調(diào)用的paintEvent()留下的痕跡都會(huì)清空
  '''
  #中間變量pos_tmp提取當(dāng)前點(diǎn)
  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):
  '''
   重寫鼠標(biāo)按住后松開的事件
   在每次松開后向pos_xy列表中添加一個(gè)斷點(diǎn)(-1, -1)
   然后在繪畫時(shí)判斷一下是不是斷點(diǎn)就行了
   是斷點(diǎn)的話就跳過去,不與之前的連續(xù)
  '''
  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_()

至此,終于完成了簡單的畫板程序的實(shí)現(xiàn)!

另外,如果在使用這個(gè)代碼的過程中有遇到什么問題,也歡迎向我反饋。

以上這篇Python3使用PyQt5制作簡單的畫板/手寫板實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決python調(diào)用matlab時(shí)的一些常見問題

    解決python調(diào)用matlab時(shí)的一些常見問題

    這篇文章主要介紹了解決python調(diào)用matlab時(shí)的一些常見問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • python解釋器spython使用及原理解析

    python解釋器spython使用及原理解析

    這篇文章主要介紹了python解釋器spython使用及原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 利用pyecharts讀取csv并進(jìn)行數(shù)據(jù)統(tǒng)計(jì)可視化的實(shí)現(xiàn)

    利用pyecharts讀取csv并進(jìn)行數(shù)據(jù)統(tǒng)計(jì)可視化的實(shí)現(xiàn)

    這篇文章主要介紹了利用pyecharts讀取csv并進(jìn)行數(shù)據(jù)統(tǒng)計(jì)可視化的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • python?實(shí)現(xiàn)圖片特效處理

    python?實(shí)現(xiàn)圖片特效處理

    這篇文章主要介紹了python?實(shí)現(xiàn)圖片特效處理,對(duì)于??圖片處理?,在日常生活中我們常常能夠看到的,下面我們就來利用Python來對(duì)圖片進(jìn)行特效操作,需要的朋友可以參考一下
    2022-04-04
  • Python畫圖小案例之多啦A夢叮當(dāng)貓超詳細(xì)注釋

    Python畫圖小案例之多啦A夢叮當(dāng)貓超詳細(xì)注釋

    在看了很多Python教程之后,覺得是時(shí)候做點(diǎn)什么小項(xiàng)目來練練手了,于是想來想去,用python寫了一個(gè)童年記憶的卡通人物哆啦A夢,代碼注釋無比詳細(xì)清楚,快來看看吧
    2021-09-09
  • Python微信公眾號(hào)開發(fā)平臺(tái)

    Python微信公眾號(hào)開發(fā)平臺(tái)

    這篇文章主要介紹了Python微信公眾號(hào)開發(fā)平臺(tái),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2018-01-01
  • Python利用psutil庫進(jìn)行監(jiān)控進(jìn)程和資源

    Python利用psutil庫進(jìn)行監(jiān)控進(jìn)程和資源

    psutil是Python系統(tǒng)和進(jìn)程工具庫,它提供了一種跨平臺(tái)的方式來獲取系統(tǒng)信息、管理系統(tǒng)進(jìn)程、監(jiān)控系統(tǒng)性能、操作系統(tǒng)資源等,下面就跟隨小編一起來學(xué)習(xí)psutil庫的具體應(yīng)用吧
    2024-01-01
  • Python+FuzzyWuzzy實(shí)現(xiàn)模糊匹配的示例詳解

    Python+FuzzyWuzzy實(shí)現(xiàn)模糊匹配的示例詳解

    在日常開發(fā)工作中,經(jīng)常會(huì)遇到這樣的一個(gè)問題:要對(duì)數(shù)據(jù)中的某個(gè)字段進(jìn)行匹配,但這個(gè)字段有可能會(huì)有微小的差異。本文將分享一個(gè)簡單易用的模糊字符串匹配工具包:FuzzyWuzzy,讓你輕松解決煩惱的匹配問題
    2022-04-04
  • Python如何將模塊打包并發(fā)布

    Python如何將模塊打包并發(fā)布

    這篇文章主要介紹了Python如何將模塊打包并發(fā)布,幫助大家分享自己的模塊,感興趣的朋友可以了解下
    2020-08-08
  • Python實(shí)現(xiàn)的簡單線性回歸算法實(shí)例分析

    Python實(shí)現(xiàn)的簡單線性回歸算法實(shí)例分析

    這篇文章主要介紹了Python實(shí)現(xiàn)的簡單線性回歸算法,結(jié)合實(shí)例形式分析了線性回歸算法相關(guān)原理、功能、用法與操作注意事項(xiàng),需要的朋友可以參考下
    2018-12-12

最新評(píng)論

聊城市| 东乡族自治县| 宿松县| 沙雅县| 扶绥县| 天等县| 汾西县| 台中市| 沐川县| 溆浦县| 盈江县| 利辛县| 洛隆县| 舟山市| 博白县| 梅州市| 伊川县| 东辽县| 英德市| 霍林郭勒市| 惠安县| 诏安县| 宣城市| 扬中市| 寿阳县| 土默特右旗| 紫金县| 望奎县| 扎鲁特旗| 两当县| 安陆市| 巴彦淖尔市| 洱源县| 于田县| 鹤庆县| 南京市| 邛崃市| 平泉县| 特克斯县| 鄯善县| 正蓝旗|