Issue
I need to make a new window for video output. It should have some buttons (which I'll add later), and a video output. I have the main window with audio playback capability, and I can make a video output on the main window, not the second one. The video check using magic.python executes videopop, which opens a new window (VideoWindow).
Code:
file: main.py
import sys
import magic
# bude obsahovat menu (File, Edit, About,...), Queue, v menu bude historie
from PyQt5.QtCore import QUrl, Qt
from PyQt5.QtGui import QPalette, QColor, QIcon
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QFileDialog, QWidget, QLabel, QVBoxLayout, QHBoxLayout, \
QPushButton, QStyle, QSlider
from ui import UI
class QueueWin(QMainWindow, UI):
def __init__(self, *args, **kwargs):
super(QueueWin, self).__init__(*args, **kwargs)
self.ui(self)
self.setWindowTitle('MPx') # nastavi title
self.setWindowIcon(QIcon('media-player-5.ico')) # nastavi ikonku
p = self.palette()
p.setColor(QPalette.Window, QColor(52, 51, 51)) # nastavi barvu okna
self.setPalette(p) # aplikuje barvu
self.open_file_act.triggered.connect(self.open_file)
#self.history_act.triggered.connect(self.open_history)
self.history_act.triggered.connect(self.videopop)
#self.open_act.triggered.connect(self.clr_history)
self.mediaPlayer.stateChanged.connect(self.mediastate_changed) #mení ikonku na tlačítku play
self.mediaPlayer.positionChanged.connect(self.update_position)
self.mediaPlayer.durationChanged.connect(self.duration_changed)
self.slider.valueChanged.connect(self.mediaPlayer.setPosition)
self.audioSlider.valueChanged.connect(self.mediaPlayer.setVolume)
def open_history (self):
h = History(self)
h.show()
def videopop(self):
v = VideoWindow(self)
v.show()
def credits(self):
w = Credits(self)
w.show()
def open_file(self):
filename, _ = QFileDialog.getOpenFileName(self, "Open Video")
if filename != '':
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(filename)))
self.playBtn.setEnabled(True)
self.mediaPlayer.play()
mime = magic.Magic(mime=True) # check zda je soubor video
videocheck = mime.from_file(filename)
if videocheck.find('video') != -1:
self.videopop()
print('it is video')
def position_changed(self, position):
self.slider.setValue(position)
def duration_changed(self,duration):
self.slider.setRange(0, duration)
def update_position(self, position):
self.slider.blockSignals(True)
self.slider.setValue(position)
self.slider.blockSignals(False)
def play_video(self):
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
self.mediaPlayer.pause()
else:
self.mediaPlayer.play()
def mediastate_changed(self, state):
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
else:
self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
class VideoWindow(QMainWindow, UI):
def __init__(self, *args, **kwargs):
super(VideoWindow, self).__init__(*args, **kwargs)
self.videoui(self)
self.setWindowTitle('Video') #nastavi title
self.setWindowIcon(QIcon('media-player-5.ico')) #nastavi ikonku
# http://www.iconseeker.com/search-icon/isabi/media-player-5.html <-- odkaz na ikonku
self.setGeometry(710, 290, 500, 500) #xMistoOtevreni, yMistoOtevreni, xVelikost, yVelikost
self.setMinimumSize(400, 400) # xMinimalniVelikost, yMinimalniVelikost
p = self.palette()
p.setColor(QPalette.Window, QColor(52, 51, 51)) #nastavi barvu okna
self.setPalette(p) #aplikuje barvu
class History(QMainWindow):
def __init__(self, parent=None):
super(History, self).__init__(parent)
self.setWindowTitle('Historie') # nastavi title
self.setWindowIcon(QIcon('media-player-5.ico')) # nastavi ikonku
# http://www.iconseeker.com/search-icon/isabi/media-player-5.html <-- odkaz na ikonku
self.setGeometry(710, 290, 500, 200) # xMistoOtevreni, yMistoOtevreni, xVelikost, yVelikost
self.setMinimumSize(200, 200) # xMinimalniVelikost, yMinimalniVelikost
p = self.palette()
p.setColor(QPalette.Window, QColor(52, 51, 51)) # nastavi barvu okna
self.setPalette(p) # aplikuje barvu
class Credits(QMainWindow):
def __init__(self, parent=None):
super(Credits, self).__init__(parent)
self.setWindowTitle('O programu') # nastavi title
self.setWindowIcon(QIcon('media-player-5.ico')) # nastavi ikonku
# http://www.iconseeker.com/search-icon/isabi/media-player-5.html <-- odkaz na ikonku
self.setGeometry(710, 290, 500, 200) # xMistoOtevreni, yMistoOtevreni, xVelikost, yVelikost
self.setMinimumSize(200, 200) # xMinimalniVelikost, yMinimalniVelikost
p = self.palette()
p.setColor(QPalette.Window, QColor(52, 51, 51)) # nastavi barvu okna
self.setPalette(p) # aplikuje barvu
self.label = QLabel('Autor: Tomáš Gabriel, 3.B OAUH<br>Napsáno pomocí Pythonu a PyQt5', self)
self.label.setStyleSheet("color: yellow")
self.label.adjustSize()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWin = QueueWin()
mainWin.show()
sys.exit(app.exec_())
file: UI.py
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtMultimedia import QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QPushButton, QSlider, QStyle, QHBoxLayout, QVBoxLayout, QMenuBar
class UI(object):
def ui(self, QueueWin):
QueueWin.setObjectName("QueueWin")
QueueWin.resize(600, 500)
_translate = QtCore.QCoreApplication.translate
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.centralWidget = QtWidgets.QWidget(QueueWin)
#sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
#sizePolicy.setHorizontalStretch(0)
#sizePolicy.setVerticalStretch(0)
#sizePolicy.setHeightForWidth(self.centralWidget.sizePolicy().hasHeightForWidth())
#self.centralWidget.setSizePolicy(sizePolicy)
self.openFileBtn = QPushButton("Otevrit soubor...", self.centralWidget)
self.openFileBtn.clicked.connect(self.open_file)
self.playBtn = QPushButton(self.centralWidget) # vytvori tlacitko "play"
self.playBtn.setEnabled(False)
self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
self.playBtn.clicked.connect(self.play_video)
self.slider = QSlider(Qt.Horizontal, self.centralWidget) # vytvori slider
self.slider.setRange(0, 0)
self.audioSlider = QSlider(Qt.Horizontal, self.centralWidget)
self.audioSlider.setMaximum(100)
self.audioSlider.setProperty("value", 100)
QueueWin.setCentralWidget(self.centralWidget)
# self.queue = QListView(self)
# self.queue.setAcceptDrops(True)
# self.queue.setAlternatingRowColors(True)
self.hbox = QHBoxLayout(self.centralWidget) # umisti tlacitka, slidery,... do UI
self.hbox.setContentsMargins(11, 11, 11, 11)
self.hbox.addWidget(self.openFileBtn)
self.hbox.addWidget(self.playBtn)
self.hbox.addWidget(self.slider)
self.hbox.addWidget(self.audioSlider)
self.vbox = QVBoxLayout(self.centralWidget)
#self.vbox.addWidget(videowidget)
# vbox.addWidget(self.queue)
self.vbox.addLayout(self.hbox)
#self.mediaPlayer.setVideoOutput(videowidget)
#self.mediaPlayer.positionChanged.connect(self.update_position)
#self.mediaPlayer.durationChanged.connect(self.duration_changed)
self.menuBar = QMenuBar(QueueWin)
QueueWin.setMenuBar(self.menuBar)
self.open = QtWidgets.QMenu(self.menuBar)
self.open_file_act = QtWidgets.QAction(QueueWin)
self.open.addAction(self.open_file_act)
self.open_file_act.setText(_translate("QueueWin", "Otevřít..."))
self.menuBar.addAction(self.open.menuAction())
self.open.setTitle(_translate("QueueWin", "Soubor"))
self.history = QtWidgets.QMenu(self.menuBar)
self.history_act = QtWidgets.QAction(QueueWin)
self.history.addAction(self.history_act)
self.history_act.setText(_translate("QueueWin", "Otevřít historii"))
self.menuBar.addAction(self.history.menuAction())
self.history.setTitle(_translate("QueueWin", "Historie"))
self.historyClr_act = QtWidgets.QAction(QueueWin)
self.history.addAction(self.historyClr_act)
self.historyClr_act.setText(_translate("QueueWin", "Vymazat historii"))
self.historyClr_act.setShortcut('ALT+H')
#about = self.menuBar.addMenu('Autor')
#about_act = QAction('O autorovi...', self)
#about_act.setShortcut('CTRL+A')
#about_act.triggered.connect(lambda: self.credits())
#about.addAction(about_act)
QtCore.QMetaObject.connectSlotsByName(QueueWin)
def videoui(self, VideoWindow):
VideoWindow.setObjectName("QueueWin")
VideoWindow.resize(600, 500)
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.centralWidget = QtWidgets.QWidget(VideoWindow)
self.videowidget = QVideoWidget(self.centralWidget)
VideoWindow.setCentralWidget(self.centralWidget)
self.hbox = QHBoxLayout(self.centralWidget) # umisti tlacitka, slidery,... do UI
self.hbox.setContentsMargins(11, 11, 11, 11)
self.hbox.addWidget(self.videowidget)
self.vbox = QVBoxLayout(self.centralWidget)
self.vbox.addLayout(self.hbox)
QtCore.QMetaObject.connectSlotsByName(VideoWindow)
Solution
You're not setting the video output, and the QMediaPlayer in VideoWindow
is completely useless (so you can remove that), while you should use the one created for QueueWin
and set the video output with the QVideoWidget of the other window.
The "basic" solution would be the following:
if videocheck.find('video') != -1:
videoWindow = VideoWindow(self)
self.mediaPlayer.setVideoOutput(videoWindow.videowidget)
videoWindow.show()
Be aware, though, that your code has some important issues that would require fixing.
First of all, files generated by the pyuic utility should never, ever be manually modified (read how to properly use those files in the official guidelines about using Designer).
Then, while technically working, creating a new QMainWindow with another one as parent is not suggested; you also continuously create a new window everytime the function is called, while you should reuse any existing window. A more proper approach would be to create the child windows when creating the main one, and show them when required, in this way you can already set up the video output for the separate video widget.
Also note that you don't need to use an external module to check if the media actually has video: just use the videoAvailableChanged
signal and show the video window if the argument is True
(you cannot just check isVideoAvailable()
right after setMedia()
, as that function is asynchronous).
Finally, if you're not using any of the QMainWindow features (menu, toolbars, dock widgets, status bar), just use a basic QWidget instead.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.