Python app 03 use PyQT to create a video player instance, pythonpyqt
Two Python GUI packages, Tkinter and PyQT, were recently studied. The underlying layers of these two GUI packages are Tcl/Tk and QT. In contrast, I think PyQT is more convenient to use and has more functions. This article uses PyQT to implement a video player and demonstrates the basic usage of PyQT.
Video Player
Release the completed code first. The Code is based on Python 3.5:
Import timeimport sysfrom PyQt4 import QtGui, QtCorefrom PyQt4.phonon import Phononclass 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: returnclass 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 = QtG Ui. QPushButton ('select file', self) self. button. clicked. connect (self. handleButton) # for display of time lapse self.info = QtGui. QLabel (self) # 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. upd Ate) def update (self): # slot lapse = self. media. currentTime ()/1000.0 self.info. setText ("% 4.2f seconds" % 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. play IngState: 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 ('stop') elif (newstate! = Phonon. LoadingState and newstate! = Phonon. bufferingState): self. button. setText ('select file') if newstate = Phonon. errorState: source = self. media. currentSource (). fileName () print ('error: cannot play:', source. toLocal8Bit (). data () print ('% s' % self. media. errorString (). toLocal8Bit (). data () if _ name _ = '_ main _': app = QtGui. QApplication (sys. argv) app. setApplicationName ('video player') window = Window () window. show () sys.exit(app.exe c _())
The Code implements an application with a GUI window for playing video files. Video Playback uses the Phonon module in PyQT. In addition, a process sends a signal every second. The window updates the video playback time after receiving the signal. The effect of this application is as follows:
The test environment is Mac OSX El Capitan.
View Section
After writing this code, I found that this code is simple, but involves several important mechanisms. You can use PyQT exercises. The following is a brief description of the Code. The first part is the main program section:
app = QtGui.QApplication(sys.argv)...window = Window()window.show()sys.exit(app.exec_())
In the PyQT program, QApplication is the top-level object, which refers to the entire GUI application. We created an application object at the beginning of the program, and finally called exec _ () to run the application. Sys. exit () is used to require the application to exit the program cleanly after the main loop ends. The beginning and end of the PyQT program are similar fixed routines. The key lies in the defined QWidget object.
The custom Window class inherits from QWidget. In fact, QWidget is the base class of all user interface objects, not just a window. Tables, input boxes, and buttons are inherited from qwidgets. In a Window object, we also combine objects such as QPushButton and QLabel to represent a button and a text box respectively. They are arranged on the Window interface through QGridLayout, that is, the following code:
# layoutlayout = QtGui.QGridLayout(self)...layout.addWidget(self.info, 4, 1, 1, 3)layout.addWidget(self.button, 5, 1, 1, 3)
QGridLayout divides the interface into grids and attaches a view object to a specific grid position. For example, addWidget () (self.info, 4, 1, 1, 3) indicates to place a text box object in the 4th rows and 1st columns. This text box occupies 1 row vertically and 3 columns horizontally. In this way, the positional relationship of the upper and lower layers is determined by the layout. In addition to grid layout, PyQT also supports other forms of layout, such as horizontal stacking and vertical stacking.
In addition to QWidget, PyQT also provides frequently used dialog boxes, such:
Self. path = QtGui. QFileDialog. getOpenFileName (self, self. button. text ())
The QFileDialog dialog box is used to select a file. The dialog box will access the path of the selected file. In addition to file selection, the dialog box also includes the confirmation dialog box, file input dialog box, and color dialog box. These dialogs provide many common GUI input functions. By using these dialog boxes, you can reduce the workload for programmers to develop from scratch.
Multithreading
The main line of the GUI is usually left to the application as the main loop. A lot of other work needs to be done through other threads. PyQT multi-thread programming is very simple. You only need to rewrite the QThread run () method:
class PollTimeThread(QtCore.QThread): def __init__(self, parent): super(PollTimeThread, self).__init__(parent) def run(self): ...
After creating a thread, you only need to call the start () method to run it:
Self. thread = PollTimeThread ()... self. thread. start () # start the thread... self. thread. terminate () # terminate the thread
Signal and slot
Asynchronous processing is often used in GUI. For example, click a button and call the corresponding callback function. QT's signal-slot mechanism is designed to solve asynchronous processing problems. We have created a signal in the thread and sent a signal through the emit () method:
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
With the signal, we can connect the signal to a "slot", which is actually the callback function corresponding to the signal:
self.thread.update.connect(self.update)
When a signal is sent, the "slot" is called. In this example, the video playing time is updated. The "signal and slot" in QT is a common mechanism. Some components, such as buttons, preset the "click" signal, which can be directly mapped to the "slot ". For example, in the Code:
self.button.clicked.connect(self.handleButton)
In addition, Phonon is a very useful multimedia module, which is easy to use. You can refer to the Code itself and will not repeat it here.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.