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

使用Python來做一個(gè)屏幕錄制工具的操作代碼

 更新時(shí)間:2020年01月18日 08:48:44   作者:編程入門到放棄  
本文給大家分享使用Python來做一個(gè)屏幕錄制工具,通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一、寫在前面

作為一名測試,有時(shí)候經(jīng)常會(huì)遇到需要錄屏記錄自己操作,方便后續(xù)開發(fā)同學(xué)定位。以前都是用ScreenToGif來錄屏制作成動(dòng)態(tài)圖,偶爾的機(jī)會(huì)看到python也能實(shí)現(xiàn)。那就趕緊學(xué)習(xí)下。

二、效果展示

三、知識(shí)串講

這次要講的東西可能比較多了,涉及到pyqt5 GUI軟件的制作、QThread多線程的使用、Sikuli庫的圖形操作、win32庫的模擬鍵盤操作、cv2庫的寫視頻文件等。下面我們一點(diǎn)點(diǎn)來蠶食我這次寫的代碼。

1、GUI界面制作

這次我用的是現(xiàn)成的Pyqt5界面布局類,QVBoxLayout。這個(gè)類可以快速協(xié)助我完成按鈕的垂直分布,而且按鈕添加也更方便。

button1 = QPushButton("自定義錄屏")
layout.addWidget(button1)

兩行代碼就完成了按鈕的命名和添加。我之前玩qt時(shí),用的都是qt的UI界面,對(duì)應(yīng)生成的組件代碼也比較復(fù)雜。因此,在開發(fā)一些少量按鈕、簡單布局時(shí)可以用QVBoxLayout類。如果喜歡水平布局,可以用QHBoxLayout類,使用方法是一樣的。

另外,在按鈕點(diǎn)擊關(guān)聯(lián)的功能函數(shù),即work()方法時(shí),如果想帶參數(shù),可以通過lambda匿名函數(shù)來實(shí)現(xiàn)。這 也是個(gè)小技巧。

# 不帶參數(shù)
button1.clicked.connect(self.work)
# 帶參數(shù)
button1.clicked.connect(lambda: self.work(1))

2、QThread類的多線程使用

因?yàn)殇浧凉ぞ哂虚_始和停止兩個(gè)功能,一開始時(shí)我用的是單線程,發(fā)現(xiàn)工具就會(huì)卡死。查了一些資料,發(fā)現(xiàn)針對(duì)這種情況,應(yīng)該要使用多線程來實(shí)現(xiàn),而QT庫中本身就有多線程類--QThread。

使用方法是通過繼承QThread類,重寫run方法來實(shí)現(xiàn)的。

(但是其實(shí)這種使用方法,QT大神們是不贊成這樣使用的,我會(huì)在第2篇文章中再簡單說明更好的多線程使用方法)

這 里要注意,work()函數(shù)必須是Ui_Mainwindow類方法,因?yàn)槿绻皇穷惙椒?,?huì)在運(yùn)行GUI時(shí)導(dǎo)致生命周期直接結(jié)束,導(dǎo)致錄屏代碼沒見運(yùn)行就報(bào)錯(cuò)退出。

class WorkThread(QThread):
  def __init__(self, n):
    super(WorkThread, self).__init__()
    self.n = n

  def run(self):
    XXXXX

3、sikuli庫圖形識(shí)別

由于這個(gè)庫的使用方法和介紹,我在之前的博客里已經(jīng)提過 了。因此只簡單地呈現(xiàn)下代碼。這段代碼主要是為了自定義錄屏?xí)r,可以獲取選擇范圍的坐標(biāo)值,并傳值給recording函數(shù),從而完成自定義錄屏功能。

def SelectRegion():
  jvmPath = jpype.get_default_jvm_path()
  jpype.startJVM(jvmPath, '-ea', '-Djava.class.path=F:\\sikuli\\1\\sikulixapi.jar') #加載jar包路徑
  Screen = jpype.JClass('org.sikuli.script.Screen')
  myscreen = Screen()
  region = myscreen.selectRegion() # 自定義獲取屏幕范圍
  return region

4、win32庫模擬鍵盤操作

其實(shí)這個(gè)庫不用也是可以的,我為什么要用呢?主要是為了方便用戶在進(jìn)行錄屏?xí)r,能自動(dòng)將工具界面縮小。一切為了用戶嘛!

以下這段代碼 是為了縮小工具窗口,其中91表示左win鍵,40表示方向向下鍵。****即win+向下鍵是可以實(shí)現(xiàn)窗口縮小功能的。****keybd_event(91, 0, 0, 0)表示按下win鍵,

keybd_event(91, 0, win32con.KEYEVENTF_KEYUP, 0)則是松開win鍵。

另外,這里為什么要加 上sleep(0.5)?這是因?yàn)樵诎聪聎in鍵后要延遲按方向鍵,不然是 不起作用的。

def Minimize_Window():
  win32api.keybd_event(91, 0, 0, 0)
  time.sleep(0.5)
  win32api.keybd_event(40, 0, 0, 0)
  time.sleep(0.5)
  win32api.keybd_event(91, 0, win32con.KEYEVENTF_KEYUP, 0)
  win32api.keybd_event(40, 0, win32con.KEYEVENTF_KEYUP, 0)

5、錄屏主代碼

這段代碼其實(shí)網(wǎng)上已經(jīng)有很多類似的代碼,并且我已經(jīng)加了注釋,相信大家應(yīng)該能理解。這里我想注明下的是:如何停止錄屏。

如果大家有去 網(wǎng)上查如何停止錄屏的方法,很多人都會(huì)寫以下代碼:

if cv2.waitKey(1) & 0xFF == ord('q'):
  break

然后告訴你,按q鍵就會(huì)停止錄屏。但是你會(huì)發(fā)現(xiàn),實(shí)際情況根本停止不了,為什么呢?因?yàn)檫€ 有一句屏幕顯示的代碼:

cv2.imshow('imm', img_bgr)
if cv2.waitKey(1) & 0xFF == ord('q'):
  break

如果你不親自執(zhí)行一次,你以為會(huì)萬事大吉,但你錯(cuò)了。這樣寫,會(huì)導(dǎo)致你的電腦屏幕被每一幀畫面給撐暴!因?yàn)橛玫膚hile True,因此每一幀畫面都會(huì)顯示,即1S 25幀畫面會(huì)不停地顯示在你桌面上!

因此,綜上的問題,我采用了一種取巧的方法:在錄屏開始時(shí)生成一個(gè)標(biāo)記文件,通過標(biāo)記文件是否被刪除來判斷是否要停止錄屏功能。

四、示例代碼

1、工具GUI界面代碼:

# coding=utf-8
# @Software : PyCharm
#Python學(xué)習(xí)群827513319


import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import time
import win32api,win32con
from recording import *

class WorkThread(QThread):
  def __init__(self, n):
    super(WorkThread, self).__init__()
    self.n = n

  def run(self):
    if self.n == 1:
      Minimize_Window()
      Recording(1)
    elif self.n == 2:
      Minimize_Window()
      Recording(2)
    else:
      StopRecording()

def Minimize_Window():
  win32api.keybd_event(91, 0, 0, 0)
  time.sleep(0.5)
  win32api.keybd_event(40, 0, 0, 0)
  time.sleep(0.5)
  win32api.keybd_event(91, 0, win32con.KEYEVENTF_KEYUP, 0)
  win32api.keybd_event(40, 0, win32con.KEYEVENTF_KEYUP, 0)

class Ui_Mainwindow():
  def setupUi(self, top):
    # 垂直布局類QVBoxLayout
    layout = QVBoxLayout(top)
    # 添加錄屏相關(guān)按鈕
    button1 = QPushButton("自定義錄屏")
    layout.addWidget(button1)
    button2 = QPushButton("全屏錄屏")
    layout.addWidget(button2)
    button3 = QPushButton("停止錄屏")
    layout.addWidget(button3)
    self.text = QPlainTextEdit('歡迎使用!')
    layout.addWidget(self.text)
    button1.clicked.connect(lambda: self.work(1))
    button2.clicked.connect(lambda: self.work(2))
    button3.clicked.connect(lambda: self.work(3))

  def work(self, n):
    if n == 1 :
      print('已選擇自定義錄屏:')
      self.text.setPlainText('正在錄屏中,請(qǐng)等待……')
    elif n == 2 :
      print('已選擇全屏錄屏:')
      self.text.setPlainText('正在錄屏中,請(qǐng)等待……')
    else:
      print('已選擇結(jié)束錄屏:')
      self.text.setPlainText('錄屏結(jié)束!(點(diǎn)擊關(guān)閉按鈕,可退出程序!)')
    self.workThread = WorkThread(n)
    self.workThread.start()

if __name__ == "__main__":
  app = QApplication(sys.argv)
  top = QWidget()
  top.setWindowTitle('錄屏小工具')
  top.resize(300, 170)
  ui = Ui_Mainwindow()
  ui.setupUi(top)
  top.show()
  sys.exit(app.exec_())# coding=utf-8

2、錄屏函數(shù)

# coding=utf-8
# @Software : PyCharm

from PIL import ImageGrab
import numpy as np
import cv2
import os
import jpype

def Recording(tag=1):
  # 錄屏開始時(shí)創(chuàng)建test.txt,作為結(jié)束錄屏的條件
  #Python學(xué)習(xí)群827513319
  if not os.path.exists('test.txt'):
    f = open('test.txt', 'w')
    f.close()
  # 根據(jù)tag值判斷自定義錄屏或全錄屏
  if tag == 1:
    r = SelectRegion()
    record_region = (r.x, r.y, r.w + r.x, r.h + r.y) # 自定義錄屏的范圍(左上坐標(biāo)、右下坐標(biāo))
  elif tag == 2:
    record_region = None
  image = ImageGrab.grab(record_region) # 獲取指定范圍的屏幕對(duì)象
  width, height = image.size
  fourcc = cv2.VideoWriter_fourcc(*'XVID')
  video = cv2.VideoWriter('test.avi', fourcc, 25, (width, height)) # 默認(rèn)視頻為25幀
  while True:
    captureImage = ImageGrab.grab(record_region) # 抓取指定范圍的屏幕
    frame = cv2.cvtColor(np.array(captureImage), cv2.COLOR_RGB2BGR)
    video.write(frame) # 將每幀畫面寫視頻文件
    # 停止錄屏的條件:test.txt被刪除
    if not os.path.exists('test.txt'):
      break
  video.release()
  cv2.destroyAllWindows()

def SelectRegion():
  jvmPath = jpype.get_default_jvm_path()
  jpype.startJVM(jvmPath, '-ea', '-Djava.class.path=F:\\sikuli\\1\\sikulixapi.jar') #加載jar包路徑
  Screen = jpype.JClass('org.sikuli.script.Screen')
  myscreen = Screen()
  region = myscreen.selectRegion() # 自定義獲取屏幕范圍
  return region

def StopRecording():
  os.remove('test.txt') #停止錄屏的觸發(fā)條件

if __name__ == "__main__":
  Recording()

五、總結(jié)

至此,基本實(shí)現(xiàn)了錄屏小工具的代碼開發(fā)。但是如果你是對(duì)代碼中的相關(guān)庫不熟悉,或者都沒下載相關(guān)的庫,那我相信你還會(huì)遇到很多坑。因此,為了方便一些小伙伴能快速把代碼跑起來,我將在下一篇文章中講講我在開發(fā)時(shí)遇到的一些坑,方便大家能避免這些問題。好了,今天就先到這里!Bye!

以上所述是小編給大家介紹的使用Python來做一個(gè)屏幕錄制工具的操作代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • python 瀑布線指標(biāo)編寫實(shí)例

    python 瀑布線指標(biāo)編寫實(shí)例

    這篇文章主要介紹了python 瀑布線指標(biāo)編寫實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • 對(duì)于Python深淺拷貝的理解

    對(duì)于Python深淺拷貝的理解

    這篇文章主要介紹了對(duì)于Python深淺拷貝的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • PyTorch深度學(xué)習(xí)LSTM從input輸入到Linear輸出

    PyTorch深度學(xué)習(xí)LSTM從input輸入到Linear輸出

    這篇文章主要為大家介紹了PyTorch深度學(xué)習(xí)LSTM從input輸入到Linear輸出深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • python中的三種注釋方法

    python中的三種注釋方法

    這篇文章主要介紹了python中的三種注釋方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • python實(shí)現(xiàn)音樂下載器

    python實(shí)現(xiàn)音樂下載器

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)音樂下載器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 淺談Python中os模塊及shutil模塊的常規(guī)操作

    淺談Python中os模塊及shutil模塊的常規(guī)操作

    這篇文章主要介紹了淺談Python中os模塊及shutil模塊的常規(guī)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • python程序主動(dòng)退出進(jìn)程的五種方式

    python程序主動(dòng)退出進(jìn)程的五種方式

    對(duì)于如何結(jié)束一個(gè)Python程序或者用Python操作去結(jié)束一個(gè)進(jìn)程等,Python本身給出了好幾種方法,而這些方式也存在著一些區(qū)別,對(duì)相關(guān)的幾種方法看了并實(shí)踐了下,同時(shí)也記錄下,需要的朋友可以參考下
    2024-02-02
  • Python使用sys.path查看當(dāng)前的模塊搜索路徑

    Python使用sys.path查看當(dāng)前的模塊搜索路徑

    sys.path 是 Python 中的一個(gè)列表,它用于存儲(chǔ)模塊搜索路徑,當(dāng)你使用 import 語句導(dǎo)入一個(gè)模塊時(shí),Python 會(huì)按照 sys.path 列表中的路徑順序來查找這個(gè)模塊,本文給大家介紹了Python使用sys.path查看當(dāng)前的模塊搜索路徑,需要的朋友可以參考下
    2025-02-02
  • 通過底層源碼理解YOLOv5的Backbone

    通過底層源碼理解YOLOv5的Backbone

    yolov5的特征提取網(wǎng)絡(luò)兼顧速度與精度,將PAN與PFN深度融合,對(duì)不同尺度魯棒性強(qiáng),可以即插即用,后接不同的檢測器,下面這篇文章主要給大家介紹了關(guān)于如何通過底層源碼理解YOLOv5的Backbone的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • python變量類型、輸入、輸出運(yùn)算符介紹舉例

    python變量類型、輸入、輸出運(yùn)算符介紹舉例

    Python是一種功能強(qiáng)大的編程語言,支持多種數(shù)據(jù)類型和運(yùn)算符,它強(qiáng)調(diào)代碼的可讀性和簡潔性,變量在Python中是動(dòng)態(tài)類型的,不需要顯式聲明類型,這篇文章主要介紹了python變量類型、輸入、輸出運(yùn)算符的相關(guān)資料,需要的朋友可以參考下
    2024-11-11

最新評(píng)論

济南市| 牙克石市| 大理市| 华坪县| 手游| 泽普县| 德惠市| 凌海市| 锡林郭勒盟| 辽中县| 溧水县| 澜沧| 河津市| 太保市| 出国| 楚雄市| 新蔡县| 铜陵市| 正蓝旗| 四子王旗| 鹤庆县| 夏邑县| 新河县| 勐海县| 祁门县| 大厂| 筠连县| 南城县| 巴林左旗| 元谋县| 石首市| 磐石市| 洪雅县| 莱芜市| 汽车| 大冶市| 银川市| 雅江县| 承德县| 宁津县| 尼勒克县|