Unsolved Problem with Show / Hide QGrahicsVideoItem child of other QGraphicsItem (Python)
-
Hello,
I'm trying to show a video over an image on a scene. I'm using QGraphicsPixmapItem as a parent of a QGraphicsVideoItem.
Working code:
import sys from PySide2.QtCore import QUrl from PySide2.QtMultimedia import QMediaPlayer from PySide2.QtMultimediaWidgets import QGraphicsVideoItem from PySide2.QtWidgets import QGraphicsScene, QApplication, QGraphicsView, QGraphicsEllipseItem, \ QPushButton IMAGE_PATH = "<path to jpg>" VIDEO_PATH = "<path to mp4>" class ImageItem(QGraphicsPixmapItem): def __init__(self, image_path, parent=None): super(ImageItem, self).__init__(image_path, parent) self.image = QImage(image_path) self.setPixmap(QPixmap.fromImage(self.image)) class PlayableItem(ImageItem): def __init__(self, image_path, clip_path, parent = None): super(PlayableItem, self).__init__(image_path, parent) self._media_player = QMediaPlayer() self._media_player.setMuted(True) self._video_widget = QGraphicsVideoItem(self) self._media_player.setVideoOutput(self._video_widget) self._media_player.setMedia(QUrl.fromLocalFile(clip_path)) self.show_video() def show_video(self): self._video_widget.show() def hide_video(self): self._video_widget.hide() if __name__ == '__main__': app = QApplication(sys.argv) scene = QGraphicsScene() item = PlayableItem(IMAGE_PATH, VIDEO_PATH) scene.addItem(item) button = QPushButton("Show") button.clicked.connect(item.show_video) button2 = QPushButton("Hide") button2.clicked.connect(item.hide_video) scene.addWidget(button) proxy = scene.addWidget(button2) proxy.setPos(80,0) view = QGraphicsView() view.setScene(scene) view.show() item.setPos(0,40) view.resize(800,600) sys.exit(app.exec_())
This code works ok and the hide and show buttons can be used to show and hide the video item over the image.
However, If the video item is hidden on the initialization, just changing the last line of the constructor of PlayableItem to self.hide_video(),
the show and hide buttons doesn't do what is expected anymore. The video is never shown. Any clue on why is it happening?I have also tried to set the ImageItem class to inherit from QGraphicsEllipseItem and I get the same behavior.
Other thing I have tried is to change the video attribute self._video_widget = QGraphicsVideoItem(self) to a QGraphicsEllipseItem and it works and show and hide, it doesn't mind I set it to show or hide on the constructor. So I guess it's something with the QGraphicsVideoItem.Not working code:
import sys from PySide2.QtCore import QUrl from PySide2.QtMultimedia import QMediaPlayer from PySide2.QtMultimediaWidgets import QGraphicsVideoItem from PySide2.QtWidgets import QGraphicsScene, QApplication, QGraphicsView, QGraphicsEllipseItem, \ QPushButton IMAGE_PATH = "<path to jpg>" VIDEO_PATH = "<path to mp4>" class ImageItem(QGraphicsPixmapItem): def __init__(self, image_path, parent=None): super(ImageItem, self).__init__(image_path, parent) self.image = QImage(image_path) self.setPixmap(QPixmap.fromImage(self.image)) class PlayableItem(ImageItem): def __init__(self, image_path, clip_path, parent = None): super(PlayableItem, self).__init__(image_path, parent) self._media_player = QMediaPlayer() self._media_player.setMuted(True) self._video_widget = QGraphicsVideoItem(self) self._media_player.setVideoOutput(self._video_widget) self._media_player.setMedia(QUrl.fromLocalFile(clip_path)) self.hide_video() def show_video(self): self._video_widget.show() def hide_video(self): self._video_widget.hide() if __name__ == '__main__': app = QApplication(sys.argv) scene = QGraphicsScene() item = PlayableItem(IMAGE_PATH, VIDEO_PATH) scene.addItem(item) button = QPushButton("Show") button.clicked.connect(item.show_video) button2 = QPushButton("Hide") button2.clicked.connect(item.hide_video) scene.addWidget(button) proxy = scene.addWidget(button2) proxy.setPos(80,0) view = QGraphicsView() view.setScene(scene) view.show() item.setPos(0,40) view.resize(800,600) sys.exit(app.exec_())
-
Hi,
Did you try to change the Z value of your items ?
-
Yes I tried to set self._videoWidget.setZValue(100) and self.setZValue(-100). But nothing changes. Can a child be behind the parent?
I have also tried to self.setOpacity(0.5) to see if the video is behind and it's not. -
IIRC, QGraphicsVideoItem has special handling as it needs a native window handle and thus I wonder if you are hitting some issue with that.
Out of curiosity, why are you using a QGraphicsScene for that part ?
-
@SGaist said in Problem with Show / Hide QGrahicsVideoItem child of other QGraphicsItem (Python):
are you using a QGraphicsScene for
Thank you @SGaist . I have a workaround for this using setSize(0,0) to hide and other setSize to show the video at the expected size.
We are developing a game. We have a main interface with buttons, widget, etc, and inside of this a view and scene with the game itself. The game have some pieces that need to be sorted and the video is a "hint" for each piece. We have the video inside the scene because we need to use as much horizontal space as possible to show the pieces. I hope my explanation is not too cryptic.
-
No no, not cryptic at all. Thanks for the feedback !