Error sending value to a variable

0

I have this code that is from a media player however I get an error when trying to send the value of the selected file to the variable VIDEO_PATH .

Here is the code:

import sys
from functools import partial
from PyQt5.QtCore import QEvent, QUrl, Qt
from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QMainWindow,
                             QWidget, QPushButton, QSlider,
                             QVBoxLayout)
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer, QAudio
from PyQt5.QtMultimediaWidgets import QVideoWidget

def dragEnterEvent(self, e):
    if e.mimeData().hasFormat('text/uri-list'):
        e.accept()
    else:
        e.ignore()


def dropEvent(self, e):
    if e.mimeData().hasUrls:
        for url in e.mimeData().urls():
            e.setDropAction(QtCore.Qt.CopyAction)
            e.accept()
            file = str(url.toLocalFile())
    else:
        e.ignore()


# Ruta del archivo.
VIDEO_PATH = file

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()


        self.widget = QWidget(self)
        self.layout = QVBoxLayout()
        self.bottom_layout = QHBoxLayout()

        # Control de reproducción de video de Qt.
        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer()
        self.media_player.setMedia(
            QMediaContent(QUrl.fromLocalFile(VIDEO_PATH)))
        self.media_player.setVideoOutput(self.video_widget)

        # Botones de reproducción y pausa.
        self.play_button = QPushButton("Pausa", self)
        self.stop_button = QPushButton("Detener", self)

        # Deslizadores para el volumen y transición del video.
        self.seek_slider = QSlider(Qt.Horizontal)
        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(self.media_player.volume())
        self.seek_slider.sliderMoved.connect(self.media_player.setPosition)
        self.volume_slider.sliderMoved.connect(self.media_player.setVolume)
        self.media_player.positionChanged.connect(self.seek_slider.setValue)
        self.media_player.durationChanged.connect(
            partial(self.seek_slider.setRange, 0))

        # Acomodar controles en la pantalla.
        self.layout.addWidget(self.video_widget)
        self.layout.addLayout(self.bottom_layout)
        self.bottom_layout.addWidget(self.play_button)
        self.bottom_layout.addWidget(self.stop_button)
        self.bottom_layout.addWidget(self.volume_slider)
        self.layout.addWidget(self.seek_slider)

        # Conectar los eventos con sus correspondientes funciones.
        self.play_button.clicked.connect(self.play_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.media_player.stateChanged.connect(self.state_changed)

        # Se utiliza installEventFilter() para capturar eventos
        # del mouse en el control de video.
        self.video_widget.installEventFilter(self)

        # Personalizar la ventana.
        self.setWindowTitle("Reproductor de video")
        self.resize(800, 600)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.bottom_layout.setContentsMargins(0, 0, 0, 0)
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

        # Reproducir el video.
        self.media_player.play()

    def play_clicked(self):
        """
        Comenzar o resumir la reproducción.
        """
        if (self.media_player.state() in
            (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)):
            self.media_player.play()
        else:
            self.media_player.pause()

    def stop_clicked(self):
        """
        Detener la reproducción.
        """
        self.media_player.stop()

    def state_changed(self, newstate):
        """
        Actualizar el texto de los botones de reproducción y pausa.
        """
        states = {
            QMediaPlayer.PausedState: "Resumir",
            QMediaPlayer.PlayingState: "Pausa",
            QMediaPlayer.StoppedState: "Reproducir"
        }
        self.play_button.setText(states[newstate])
        self.stop_button.setEnabled(newstate != QMediaPlayer.StoppedState)

    def eventFilter(self, obj, event):
        """
        Establecer o remover pantalla completa al obtener
        el evento MouseButtonDblClick.
        """
        if event.type() == QEvent.MouseButtonDblClick:
            obj.setFullScreen(not obj.isFullScreen())
        return False
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

This is the error:

    
asked by Revsky01 27.03.2018 в 03:29
source

1 answer

1

Your code has the following important problems:

  • dragEnterEvent and dropEvent are methods that you should overwrite in the class that you want the Drag & Drop . You have them outside the class of any widget so they just do not do anything.

  • By default the Drag & Drop is disabled . You must use the setAcceptDrops method in the constructor of the class in which you want to enable it.

  • You use a global variable (although according to the conventions it is a "constant" when writing it in upper case) for the path of the file that points to file . The problem is that file does not exist anywhere at the time you define VIDEO_PATH , it's a local variable of the "method" dropEvent . This is what causes the error you show. On the other hand, you try to load the file when instantiating your class, when you still do not have an available route. Avoid global variables unless they are essential or their use is justified, the file path can perfectly be an instance attribute of your class. On the other hand, load the file in QMediPlayer when you get the path (when you do Drag & Drop with a file in this case).

Your code could initially look like this:

import sys
from functools import partial
from PyQt5.QtCore import QEvent, QUrl, Qt
from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QMainWindow,
                             QWidget, QPushButton, QSlider,
                             QVBoxLayout)
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer, QAudio
from PyQt5.QtMultimediaWidgets import QVideoWidget




class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.video_path = ''
        self.widget = QWidget(self)
        self.layout = QVBoxLayout()
        self.bottom_layout = QHBoxLayout()
        self.setAcceptDrops(True)

        # Control de reproducción de video de Qt.
        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer()
        self.media_player.setVideoOutput(self.video_widget)

        # Botones de reproducción y pausa.
        self.play_button = QPushButton("Reproducir", self, enabled=False)
        self.stop_button = QPushButton("Detener", self, enabled=False)

        # Deslizadores para el volumen y transición del video.
        self.seek_slider = QSlider(Qt.Horizontal, enabled=False)
        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(self.media_player.volume())
        self.seek_slider.sliderMoved.connect(self.media_player.setPosition)
        self.volume_slider.sliderMoved.connect(self.media_player.setVolume)
        self.media_player.positionChanged.connect(self.seek_slider.setValue)
        self.media_player.durationChanged.connect(
            partial(self.seek_slider.setRange, 0))

        # Acomodar controles en la pantalla.
        self.layout.addWidget(self.video_widget)
        self.layout.addLayout(self.bottom_layout)
        self.bottom_layout.addWidget(self.play_button)
        self.bottom_layout.addWidget(self.stop_button)
        self.bottom_layout.addWidget(self.volume_slider)
        self.layout.addWidget(self.seek_slider)

        # Conectar los eventos con sus correspondientes funciones.
        self.play_button.clicked.connect(self.play_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.media_player.mediaStatusChanged.connect(self.state_changed)
        self.media_player.stateChanged.connect(self.state_changed)

        # Se utiliza installEventFilter() para capturar eventos
        # del mouse en el control de video.
        self.video_widget.installEventFilter(self)

        # Personalizar la ventana.
        self.setWindowTitle("Reproductor de video")
        self.resize(800, 600)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.bottom_layout.setContentsMargins(0, 0, 0, 0)
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

    def play_clicked(self):
        """
        Comenzar o resumir la reproducción.
        """
        if self.media_player.state() == QMediaPlayer.PausedState:
            self.media_player.play()

        elif self.media_player.state() == QMediaPlayer.StoppedState:
            self.media_player.play()

        elif self.media_player.state() == QMediaPlayer.PlayingState:
            self.media_player.pause()

    def stop_clicked(self):
        """
        Detener la reproducción.
        """
        self.media_player.stop()

    def state_changed(self, newstate):
        if newstate == QMediaPlayer.LoadedMedia:
            print("[INFO   ]: Archivo cargado correctamente")
            self.play_button.setEnabled(True)

        elif newstate == QMediaPlayer.InvalidMedia:
            print("[WARNING]: El archivo no puede ser reproducido")
            self.play_button.setEnabled(False)

        states = {
            QMediaPlayer.PausedState: "Resumir",
            QMediaPlayer.PlayingState: "Pausa",
            QMediaPlayer.StoppedState: "Reproducir",
            QMediaPlayer.InvalidMedia: "Reproducir",
            QMediaPlayer.LoadedMedia: "Reproducir"
        }

        if newstate in states:
            self.play_button.setText(states[newstate])

        playing = self.media_player.state() == QMediaPlayer.PlayingState or \
                  self.media_player.state() == QMediaPlayer.PausedState

        self.stop_button.setEnabled(playing)
        self.seek_slider.setEnabled(playing)

    def eventFilter(self, obj, event):
        """
        Establecer o remover pantalla completa al obtener
        el evento MouseButtonDblClick.
        """
        if event.type() == QEvent.MouseButtonDblClick:
            obj.setFullScreen(not obj.isFullScreen())
        return False

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('text/uri-list'):
            e.accept()
        else:
            e.ignore()


    def dropEvent(self, e):
        if e.mimeData().hasUrls:
            url = e.mimeData().urls()[0]
            self.file_path = str(url.toLocalFile())
            self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(self.file_path)))
        else:
            e.ignore()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

There are some modifications, for example the buttons and the slider are disabled at startup or when there is not a valid file loaded. To do this, use the signal QMediaPlayer.mediaStatusChanged .

    
answered by 27.03.2018 / 11:09
source