python开发视频播放器_Python应用03 使用PyQT制作视频播放器实例

最近研究了Python的两个GUI包,Tkinter和PyQT。这两个GUI包的底层分别是Tcl/Tk和QT。相比之下,我觉得PyQT使用起来更加方便,功能也相对丰富。这一篇用PyQT实现一个视频播放器,并借此来说明PyQT的基本用法。

视频播放器

先把已经完成的代码放出来。代码基于Python 3.5:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

import time

import sys

from PyQt4import QtGui, QtCore

from PyQt4.phononimport Phonon

class PollTimeThread(QtCore.QThread):

"""

This thread works as a timer.

"""

update= QtCore.pyqtSignal()

def __init__(self, parent):

super(PollTimeThread,self).__init__(parent)

def run(self):

while True:

time.sleep(1)

if self.isRunning():

# emit signal

self.update.emit()

else:

return

class Window(QtGui.QWidget):

def __init__(self):

QtGui.QWidget.__init__(self)

# media

self.media= Phonon.MediaObject(self)

self.media.stateChanged.connect(self.handleStateChanged)

self.video= Phonon.VideoWidget(self)

self.video.setMinimumSize(200,200)

self.audio= Phonon.AudioOutput(Phonon.VideoCategory,self)

Phonon.createPath(self.media,self.audio)

Phonon.createPath(self.media,self.video)

# control button

self.button= QtGui.QPushButton('选择文件',self)

self.button.clicked.connect(self.handleButton)

# for display of time lapse

self.info= QtGui.QLabel(self)

# layout

layout= QtGui.QGridLayout(self)

layout.addWidget(self.video,1,1,3,3)

layout.addWidget(self.info,4,1,1,3)

layout.addWidget(self.button,5,1,1,3)

# signal-slot, for time lapse

self.thread= PollTimeThread(self)

self.thread.update.connect(self.update)

def update(self):

# slot

lapse= self.media.currentTime()/1000.0

self.info.setText("%4.2f 秒" % lapse)

def startPlay(self):

if self.path:

self.media.setCurrentSource(Phonon.MediaSource(self.path))

# use a thread as a timer

self.thread= PollTimeThread(self)

self.thread.update.connect(self.update)

self.thread.start()

self.media.play()

def handleButton(self):

if self.media.state()== Phonon.PlayingState:

self.media.stop()

self.thread.terminate()

else:

self.path= QtGui.QFileDialog.getOpenFileName(self,self.button.text())

self.startPlay()

def handleStateChanged(self, newstate, oldstate):

if newstate== Phonon.PlayingState:

self.button.setText('停止')

elif (newstate != Phonon.LoadingStateand

newstate != Phonon.BufferingState):

self.button.setText('选择文件')

if newstate== Phonon.ErrorState:

source= self.media.currentSource().fileName()

print ('错误:不能播放:', source.toLocal8Bit().data())

print (' %s' % self.media.errorString().toLocal8Bit().data())

if __name__== '__main__':

app= QtGui.QApplication(sys.argv)

app.setApplicationName('视频播放')

window= Window()

window.show()

sys.exit(app.exec_())

代码实现了一个有GUI窗口的应用,用来播放视频文件。视频播放利用了PyQT中的Phonon模块。此外,还有一个进程每隔一秒发出一个信号。窗口在接收到信号后,更新视频播放的时间。这个应用的效果如下:

测试运行环境为Mac OSX El Capitan。

1-2009131151091K.png

视图部分

写完这个代码之后,我发现这个代码虽然简单,但涉及了几个重要机制,可以用PyQT的练习题。下面对代码进行一些简要的说明,首先是主程序部分:

1

2

3

4

5

app= QtGui.QApplication(sys.argv)

...

window= Window()

window.show()

sys.exit(app.exec_())

在PyQT程序中,QApplication是最上层的对象,指代整个GUI应用。我们在程序的一开始创建了一个应用对象,在程序最后调用exec_()来运行这个应用。sys.exit()用来要求应用的主循环结束后干净地退出程序。PyQT程序的开始和结尾都是类似的固定套路。关键就在于其间定义的QWidget对象。

我们自定义的Window类继承自QWidget。其实QWidget是所有用户界面对象的基类,并不单单指代一个窗口。表格、输入框、按钮都继承自QWidget。在一个Window对象中,我们还组合有QPushButton和QLabel这样的对象,分别代表一个按钮和一个文本框。它们通过QGridLayout的方式,布局在Window的界面上,即下面一部分代码:

1

2

3

4

5

# layout

layout= QtGui.QGridLayout(self)

...

layout.addWidget(self.info,4,1,1,3)

layout.addWidget(self.button,5,1,1,3)

QGridLayout把界面分成网格,并把某个视图对象附着在特定的网格位置。比如说,addWidget()(self.info, 4, 1, 1, 3)表示把一个文本框对象放在第4排、第1列的位置。该文本框纵向将占据1排,横向占据3列。这样,上下层视图的位置关系就通过布局确定了下来。除了网格式的布局,PyQT还支持其他形式的布局,如横向堆砌、纵向堆砌等等,可以进一步了解。

除了QWidget,PyQT还提供了常用的对话框,如:

self.path = QtGui.QFileDialog.getOpenFileName(self, self.button.text())

这里的QFileDialog对话框用于选择文件。对话框将访问所选文件的路径。除了文件选择,对话框还有确认对话框、文件输入对话框、色彩对话框。这些对话框实现了不少常用的GUI输入功能。通过利用这些对话框,可以减少程序员从头开发的工作量。

多线程

GUI界面的主线程通常留给应用做主循环。其他的很多工作要通过其他的线程来完成。PyQT多线程编程很简单,只需要重写QThread的run()方法就可以了:

1

2

3

4

5

6

class PollTimeThread(QtCore.QThread):

def __init__(self, parent):

super(PollTimeThread,self).__init__(parent)

def run(self):

...

创建线程后,只需要调用start()方法,就可以运行:

1

2

3

4

5

self.thread= PollTimeThread()

...

self.thread.start()# 启动线程

...

self.thread.terminate()# 终止线程

信号与槽

GUI经常要用到异步处理。比如说点击某个按钮,然后调用相应的回调函数。QT的“信号与槽”(signal-slot)机制就是为了解决异步处理问题。我们在线程中创建了信号,并通过emit()方法来发出信号:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class PollTimeThread(QtCore.QThread):

"""

This thread works as a timer.

"""

update= QtCore.pyqtSignal()

def __init__(self, parent):

super(PollTimeThread,self).__init__(parent)

def run(self):

while True:

time.sleep(1)

if self.isRunning():

# emit signal

self.update.emit()

else:

return

有了信号,我们就可以给该信号连接到一个“槽”,其实就是对应于该信号的回调函数:

1

self.thread.update.connect(self.update)

每当信号被发出时,“槽”就会被调用。在这个例子中,就是更新视频播放时间。QT中的“信号与槽”是普遍存在的机制。一些组建如按键,预设了“点击”这样的信号,可以直接对应到“槽”。如代码中的:

1

self.button.clicked.connect(self.handleButton)

此外,Phonon是一个很好用的多媒体模块,使用方法也很简单,可以参考代码本身,这里不再赘述。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.cnblogs.com/vamei/p/6139513.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js 正则中冒号代表什么_javascript中正则表达式语法详解

好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉。就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,…

一个关于数学归纳法的悖论问题-续

上篇文章讲到一个悖论,这里解开悖论的什么面纱 上篇文章地址http://www.cnblogs.com/zhouyf/p/4583351.html 「游客没有输入任何新的信息」这个断言是错的。N1的情形不必说了,显然输入了新信息。对于N>1的情形,要注意,游客必须是当着所有人…

封装出现 用户.计算机,ES4封装WIN7出现[Administrator.计算机名]目录的可能解决方案...

受https://www.itiankong.net/thread-36634-1-1.html这个贴子中的思路启发,算是彻底解决了[Administrator.计算机名]目录的问题,打算把整理的方法贴出来,遇到问题的朋友也帮忙试一下是否有效。先说原理:这个问题的出现基本上和ES无…

自动化测试工具selenium python_Selenium自动化测试工具使用方法汇总

1、设置无头浏览器模式 from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options Options() chrome_options.add_argument(- -headless) chrome_options.add_argument(- -disable-gpu) class XX(object): self.driver webdriv…

数据库查找姓李的人_最通俗易懂的理解什么是数据库

1.什么是数据库呢?每个人家里都会有冰箱,冰箱是用来干什么的?冰箱是用来存放食物的地方。同样的,数据库是存放数据的地方。正是因为有了数据库后,我们可以直接查找数据。例如你每天使用余额宝查看自己的账户收益&#…

Android多媒体分析-通过MediaStore获取Audio信息

public void getAlldata() { ContentResolver cr getApplication().getContentResolver(); if (cr null) { return; } // 获取所有歌曲 Cursor cursor cr.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, …

怎么在anaconda上安装python_我是如何用Anaconda来管理Python的

Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。 Anaconda主要特点: 开源各个库之间的依赖性列出所需其他依赖包。多种开源库conda是包及其依赖项和环境的管理工具适用语言:P…

rdd分片 spark_Spark分区

一、分区的概念分区是RDD内部并行计算的一个计算单元,RDD的数据集在逻辑上被划分为多个分片,每一个分片称为分区,分区的格式决定了并行计算的粒度,而每个分区的数值计算都是在一个任务中进行的,因此任务的个数&#xf…

html5 防止脚本攻击,shell防ddos攻击脚本(二)

在上一篇shell防ddos攻击脚本(一)中,我给大家发了个脚本,那只是针对单机的,如果是在负载均衡下的话,很容易把自己的服务器ip给误封,所以这篇文章就给大家发个可以添加白名单的shell脚本.系统:centos 5.9 64位脚本内容:vi ip-dos-cc.sh#!/bin/bashnetstat -an| grep :80 |grep -…

python中配置opencv_在Windows中安装OpenCV-Python|四

目标 在本教程中,我们将学习在你的Windows系统中设置OpenCV-Python。 下面的步骤在装有Visual Studio 2010和Visual Studio 2012的Windows 7-64位计算机上进行了测试。屏幕截图展示的是VS2012。 从预编译的二进制文件安装OpenCV 下面的Python软件包将被下载并安装到…

uip UDPclient模式通信移植,当地port随机

现在移植UDPclient模式,测试广播地址. //udp_client.c /************************************************************************************************************** 文件名称: udp_client.c* 功能: uIP UDP客户端相关函数* 作者: cp1300139.com* 创建时间: 20…

react如何遍历并比较_[前端进阶] 这可能是最通俗易懂的React 渲染原理及性能优化...

如今的前端,框架横行,出去面试问到框架是常有的事。我比较常用React, 这里就写了一篇 React 基础原理的内容, 面试基本上也就问这些, 分享给大家。React 是什么React是一个专注于构建用户界面的 Javascript Library.一…

运用计算机计算包含排斥原理,离散数学包含及排斥原理.ppt

离散数学包含及排斥原理第三章 集合与关系 * 一、有限集的计数 一个集合若其组成集合的元素个数是有限的,则称作有限集。 设A1、A2为素个数分别记为|A1|,|A2| P96有限集记数有如下几个性质: a)|A1∪A2| ≤ |A1||A2| b)|A1∩A2| ≤min( |A1|,|…

基于git的工作流程

本文针对的是追求极致、快速的产品响应团队的。以下的观点和内容都是围绕这个主题,暂时不涉及个人学习和团队学习。 在说工作流程之间,想说一下我们平常工作中遇到的一些困惑或者说现象 在一个团队里,同时有好多事件要解决。有的是产品迭代&a…

c 自定义实现string类 clear_CC++语言15|类的继承和派生实现代码重用、扩充

在C中,继承是一个对象自动获取其父对象的所有属性和行为的过程。通过继承,您可以重用,扩展或修改在其他类中定义的属性和行为。通过继承,可以实现函数重写以及多态。在C中,继承另一个类的成员的类称为派生类&#xff0…

超几何分布_常见概率分布

离散分布退化分布 若r.v. 只取常数值c,即 ,这时分布函数为: 把这种分布称为退化分布或者单点分布。伯努利分布 在一次实验中,事件A出现的概率为 ,不出现的概率为 ,若用 记事件A出现的次数,则 仅取值0或1,相应的…

spring 4.0 JUnit简单的Dao,Service测试

1.AbstractTransactionalJUnit4SpringContextTests 和AbstractJUnit4SpringContextTests。我们在测试用例类要继承两种中的一个。 AbstractTransactionalJUnit4SpringContextTests提供了数据库自动回滚,也就是说测试前和测试后数据库是一样的 AbstractJUnit4SpringC…

云起智慧中心连接华为_【转发】华为智慧屏HiLink控制联动,操作指南来了!

本文转自华为智慧生活APP -> 智能 -> 酷玩页面华为智慧屏HiLink控制联动,操作指南来了!一、基本控制通过华为智慧生活APP,您可以对已绑定华为账号的智慧屏进行基本控制,操作指南如下:① 在智慧屏上登录华为账号&…

中小学电教信息计算机管理员职责,中小学电教教师岗位职责

第1篇:电教教师岗位职责电教教师岗位目标责任书一、根据学校工作计划制定学校电教工作计划。二、根据学校需要,收集、编制电教教材和资料。三、管理好电教教室、器材和设施,严格执行器材的使用归还制度。四、电教器材使用设置合理&#xff0c…

python编程口诀_少儿Python编程中的算术与技巧

在儿童Python中,使用数值进行基本运算的情况很常见。加、减、乘、除都是内置的。加法和减法通过和-号执行。 在Python shell提示中可以输入基本的算术表达式,将它当作一个计算机来使用。像计算器一样,Python接受一组操作,当按下En…