PyQt5 视频播放器:转换为面向对象的代码会阻止播放
PyQt5 VideoPlayer: Converting to Object Orientated Code Prevents Playback
我一直在研究如何将视频或直播整合到应用程序中。我发现了一些可以正常工作的功能代码:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import cv2 # OpenCV
import qimage2ndarray # for a memory leak,see gist
import sys # for exiting
# Minimal implementation...
def displayFrame():
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = qimage2ndarray.array2qimage(frame)
label.setPixmap(QPixmap.fromImage(image))
app = QApplication([])
window = QWidget()
# OPENCV
cap = cv2.VideoCapture("Vid.mp4")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
# timer for getting frames
timer = QTimer()
timer.timeout.connect(displayFrame)
timer.start(60)
label = QLabel('No Camera Feed')
button = QPushButton("Quiter")
button.clicked.connect(sys.exit) # quiter button
layout = QVBoxLayout()
layout.addWidget(button)
layout.addWidget(label)
window.setLayout(layout)
window.show()
app.exec_()
我正试图在一些面向对象的代码中使用它,目的是创建一个视频播放小部件以合并到其他应用程序中:
import cv2
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import qimage2ndarray # for a memory leak,see gist
import sys # for exiting
# Minimal implementation...
class basicWindow(QMainWindow):
def __init__(self):
super(basicWindow, self).__init__()
# OPENCV
cap = cv2.VideoCapture("Vid.mp4")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
# timer for getting frames
timer = QTimer()
timer.timeout.connect(displayFrame)
timer.start(60)
label = QLabel('No Camera Feed')
button = QPushButton("Quiter")
button.clicked.connect(sys.exit) # quiter button
layout = QVBoxLayout()
layout.addWidget(button)
layout.addWidget(label)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def displayFrame():
ret, frame = cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = qimage2ndarray.array2qimage(frame)
try:
label.setPixmap(QPixmap.fromImage(image))
except Exception as e:
print(e)
if __name__ == '__main__':
app = QApplication(sys.argv)
windowExample = basicWindow()
windowExample.show()
sys.exit(app.exec_())
我是 OO 编码和 PyQt5 的新手,所以任何关于我如何误解代码的工作方式或我遗漏了什么的建议都会很棒。我已经尝试将标签设置为全局变量,因为我不确定函数 displayFrame() 是否知道要使用 label.setPixmap
更改的标签,但除此之外我有点迷茫。
在您的第一个示例中它有效,因为 label
是一个 全局 变量,因此 displayFrame
可以访问它。
在另一种情况下,label
仅在 basicWindow
实例的 __init__
范围内声明,因此 displayFrame
对此一无所知。
让标签成为实例的成员(self.label = QLabel()
),displayFrame
成为basicWindow的方法class(def displayFrame(self):
),然后正确访问标签;请注意,您还需要使 cap
和 timer
成为实例的成员 (self
),否则它们的对象将在 __init__
[= 之后立即 "garbage collected" 36=].
class basicWindow(QMainWindow):
def __init__(self):
super(basicWindow, self).__init__()
# ...
self.cap = cv2.VideoCapture("Vid.mp4")
# ...
self.timer = QTimer()
self.timer.timeout.connect(self.displayFrame)
self.timer.start(60)
self.label = QLabel('No Camera Feed')
# ...
def displayFrame(self):
ret, frame = self.cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = qimage2ndarray.array2qimage(frame)
try:
self.label.setPixmap(QPixmap.fromImage(image))
except Exception as e:
print(e)
由于您是 OO 编程的新手,我建议您先研究 classes and instances and name resolution 如何在 python 中工作。
我一直在研究如何将视频或直播整合到应用程序中。我发现了一些可以正常工作的功能代码:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import cv2 # OpenCV
import qimage2ndarray # for a memory leak,see gist
import sys # for exiting
# Minimal implementation...
def displayFrame():
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = qimage2ndarray.array2qimage(frame)
label.setPixmap(QPixmap.fromImage(image))
app = QApplication([])
window = QWidget()
# OPENCV
cap = cv2.VideoCapture("Vid.mp4")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
# timer for getting frames
timer = QTimer()
timer.timeout.connect(displayFrame)
timer.start(60)
label = QLabel('No Camera Feed')
button = QPushButton("Quiter")
button.clicked.connect(sys.exit) # quiter button
layout = QVBoxLayout()
layout.addWidget(button)
layout.addWidget(label)
window.setLayout(layout)
window.show()
app.exec_()
我正试图在一些面向对象的代码中使用它,目的是创建一个视频播放小部件以合并到其他应用程序中:
import cv2
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import qimage2ndarray # for a memory leak,see gist
import sys # for exiting
# Minimal implementation...
class basicWindow(QMainWindow):
def __init__(self):
super(basicWindow, self).__init__()
# OPENCV
cap = cv2.VideoCapture("Vid.mp4")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
# timer for getting frames
timer = QTimer()
timer.timeout.connect(displayFrame)
timer.start(60)
label = QLabel('No Camera Feed')
button = QPushButton("Quiter")
button.clicked.connect(sys.exit) # quiter button
layout = QVBoxLayout()
layout.addWidget(button)
layout.addWidget(label)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def displayFrame():
ret, frame = cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = qimage2ndarray.array2qimage(frame)
try:
label.setPixmap(QPixmap.fromImage(image))
except Exception as e:
print(e)
if __name__ == '__main__':
app = QApplication(sys.argv)
windowExample = basicWindow()
windowExample.show()
sys.exit(app.exec_())
我是 OO 编码和 PyQt5 的新手,所以任何关于我如何误解代码的工作方式或我遗漏了什么的建议都会很棒。我已经尝试将标签设置为全局变量,因为我不确定函数 displayFrame() 是否知道要使用 label.setPixmap
更改的标签,但除此之外我有点迷茫。
在您的第一个示例中它有效,因为 label
是一个 全局 变量,因此 displayFrame
可以访问它。
在另一种情况下,label
仅在 basicWindow
实例的 __init__
范围内声明,因此 displayFrame
对此一无所知。
让标签成为实例的成员(self.label = QLabel()
),displayFrame
成为basicWindow的方法class(def displayFrame(self):
),然后正确访问标签;请注意,您还需要使 cap
和 timer
成为实例的成员 (self
),否则它们的对象将在 __init__
[= 之后立即 "garbage collected" 36=].
class basicWindow(QMainWindow):
def __init__(self):
super(basicWindow, self).__init__()
# ...
self.cap = cv2.VideoCapture("Vid.mp4")
# ...
self.timer = QTimer()
self.timer.timeout.connect(self.displayFrame)
self.timer.start(60)
self.label = QLabel('No Camera Feed')
# ...
def displayFrame(self):
ret, frame = self.cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image = qimage2ndarray.array2qimage(frame)
try:
self.label.setPixmap(QPixmap.fromImage(image))
except Exception as e:
print(e)
由于您是 OO 编程的新手,我建议您先研究 classes and instances and name resolution 如何在 python 中工作。