我是新来的类和PyQt5并试图建立使用PyQt5和OpenCV视频播放器。使用OpenCV Video Capture with PyQt4代码并进行更改,以命令转换PyQt4中成PyQt5并增加了暂停按钮,我现在有暂停,播放端的视频播放器,并退出按钮。这是工作正常的代码:
import cv2
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QPushButton,
QVBoxLayout, QFileDialog
fileName = 'C:/Users/Art/Downloads/testVideo.mp4'
class Capture():
def __init__(self):
self.capturing = False
self.c = cv2.VideoCapture(fileName)
def startCapture(self):
self.capturing = True
cap = self.c
while(self.capturing):
ret, frame = cap.read()
cv2.imshow("Capture", frame)
cv2.waitKey(5)
cv2.destroyAllWindows()
def endCapture(self):
self.capturing = False
def pauseCapture(self):
if cv2.waitKey(0) & 0xFF == ord('p'): # Pause
self.capturing = False
def quitCapture(self):
cap = self.c
cv2.destroyAllWindows()
cap.release()
QtCore.QCoreApplication.quit()
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle('Control Panel')
self.capture = Capture()
self.start_button = QPushButton('Start', self)
self.start_button.clicked.connect(self.capture.startCapture)
self.end_button = QPushButton('End', self)
self.end_button.clicked.connect(self.capture.endCapture)
self.pause_button = QPushButton('Pause', self)
self.pause_button.clicked.connect(self.capture.pauseCapture)
self.quit_button = QPushButton('Quit', self)
self.quit_button.clicked.connect(self.capture.quitCapture)
vbox = QVBoxLayout(self)
vbox.addWidget(self.start_button)
vbox.addWidget(self.end_button)
vbox.addWidget(self.pause_button)
vbox.addWidget(self.quit_button)
self.setLayout(vbox)
self.setGeometry(100, 100, 200, 200)
self.show()
if __name__== '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())
到目前为止,我硬编码的视频文件的名称和路径到代码(文件名)。现在,我想添加加载按钮,可以让用户选择视频。事情是这样的:
self.load_button = QPushButton('Load', self)
self.load_button.clicked.connect(self.pick_video)
def pick_video():
dialog = QtGui.QFileDialog()
fileName = dialog.getExistingDirectory(None,
"Select Folder")
return fileName
并加入负载按钮现有的按钮,像这样的列表:
vbox.addWidget(self.load_button)
我的问题是我不知道我怎么能合并到现有的代码这一点。如果我把它里面Window类,它抛出我的错误。我的问题是如何添加像这样到我现有的代码,使得用户可以按下加载按钮后,选择视频文件。
编辑:根据@ekhumoro改变代码后,我得到了这样的事情:
import cv2
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QPushButton,
QVBoxLayout, QFileDialog
class Capture():
def __init__(self):
self.capturing = False
def startCapture(self, path):
self.capturing = True
self.c = cv2.VideoCapture(path)
while self.capturing:
ret, frame = self.c.read()
cv2.imshow("Capture", frame)
cv2.waitKey(5)
cv2.destroyAllWindows()
def endCapture(self):
self.capturing = False
def pauseCapture(self):
if cv2.waitKey(0) & 0xFF == ord('p'): # Pause
self.capturing = False
def quitCapture(self):
cap = self.c
cv2.destroyAllWindows()
cap.release()
QtCore.QCoreApplication.quit()
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle('Control Panel')
self.capture = Capture()
self.start_button = QPushButton('Start', self)
self.start_button.clicked.connect(self.start)
self.end_button = QPushButton('End', self)
self.end_button.clicked.connect(self.capture.endCapture)
self.pause_button = QPushButton('Pause', self)
self.pause_button.clicked.connect(self.capture.pauseCapture)
self.quit_button = QPushButton('Quit', self)
self.quit_button.clicked.connect(self.capture.quitCapture)
vbox = QVBoxLayout(self)
vbox.addWidget(self.start_button)
vbox.addWidget(self.end_button)
vbox.addWidget(self.pause_button)
vbox.addWidget(self.quit_button)
self.setLayout(vbox)
self.setGeometry(100, 100, 200, 200)
self.show()
def start(self):
path = QtWidgets.QFileDialog.getOpenFileName(self)[0]
if path:
self.capture.startCapture(path)
if __name__== '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())
但是,当我运行此代码,我得到这个错误:AttributeError的:“窗口”对象有没有属性“开始”。另一件事是,我想为这个过程中一个单独的按钮,这意味着一旦用户运行代码,在打开时,他/她可以点击该按钮的窗口(我们称之为加载按钮),然后选择视频文件,我不要在此代码中看到。我缺少的东西的地方?或者,也许将重新排列的代码是不是@ekhumoro意思。
重新排列代码,以便startCapture
需要path
参数。然后通过从在启动按钮插槽中的文件对话框的路径:
class Capture():
def __init__(self):
self.capturing = False
def startCapture(self, path):
self.capturing = True
self.c = cv2.VideoCapture(path)
while self.capturing:
ret, frame = self.c.read()
cv2.imshow("Capture", frame)
cv2.waitKey(5)
cv2.destroyAllWindows()
class Window(QtWidgets.QWidget):
def __init__(self):
...
self.start_button = QPushButton('Start', self)
self.start_button.clicked.connect(self.start)
...
def start(self):
path = QtWidgets.QFileDialog.getOpenFileName(self)[0]
if path:
self.capture.startCapture(path)
下面是一个完整的替代实现:
import cv2
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QPushButton,QVBoxLayout, QFileDialog
class Capture():
def __init__(self):
self.capturing = False
self.c = None
def setVideoFile(self, path):
if self.c is not None:
cv2.destroyAllWindows()
self.c.release()
self.c = cv2.VideoCapture(path)
self.startCapture()
def startCapture(self):
self.capturing = True
cap = self.c
while(self.capturing):
ret, frame = cap.read()
cv2.imshow("Capture", frame)
cv2.waitKey(5)
cv2.destroyAllWindows()
def endCapture(self):
self.capturing = False
def pauseCapture(self):
if cv2.waitKey(0) & 0xFF == ord('p'): # Pause
self.capturing = False
def quitCapture(self):
cap = self.c
cv2.destroyAllWindows()
cap.release()
QtCore.QCoreApplication.quit()
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.setWindowTitle('Control Panel')
self.capture = Capture()
self.open_button = QPushButton('Open', self)
self.open_button.clicked.connect(self.open)
self.start_button = QPushButton('Start', self)
self.start_button.clicked.connect(self.capture.startCapture)
self.end_button = QPushButton('End', self)
self.end_button.clicked.connect(self.capture.endCapture)
self.pause_button = QPushButton('Pause', self)
self.pause_button.clicked.connect(self.capture.pauseCapture)
self.quit_button = QPushButton('Quit', self)
self.quit_button.clicked.connect(self.capture.quitCapture)
vbox = QVBoxLayout(self)
vbox.addWidget(self.open_button)
vbox.addWidget(self.start_button)
vbox.addWidget(self.end_button)
vbox.addWidget(self.pause_button)
vbox.addWidget(self.quit_button)
self.setLayout(vbox)
self.setGeometry(100, 100, 200, 200)
self.show()
def open(self):
path = QtWidgets.QFileDialog.getOpenFileName(self)[0]
if path:
self.capture.setVideoFile(path)
if __name__== '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())