Как выбрать файл для видео плеера - PullRequest
0 голосов
/ 08 февраля 2019

Я новичок в классах и PyQt5 и пытаюсь собрать видеоплеер, используя PyQt5 и Opencv.Используя код в OpenCV Video Capture с 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())

До сих пор я жестко закодировал имя видеофайла и его путь в код (fileName).Теперь я хочу добавить кнопку загрузки, которая позволит пользователю выбрать видео.Примерно так:

 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:Объект 'Window' не имеет атрибута 'start' .Другое дело, что я хочу иметь отдельную кнопку для этого процесса, а это означает, что как только пользователь запустит код, в открывшемся окне он / она может нажать на эту кнопку (давайте назовем ее кнопкой загрузки), а затем выбрать видеофайл, который я не вижу в этом коде.Я что-то упустил где-то?Или, может быть, переставленный код не то, что имел в виду @ekhumoro.

1 Ответ

0 голосов
/ 08 февраля 2019

Измените код так, чтобы 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())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...