I'm trying to load a 720p video with a QGraphicsVideoItem in a QGraphicsView, but the output is no where near the size. How do I get it to stretch to the maximum size possible (based on window size)?
MRE:
from PySide6 import QtCore as qtc
from PySide6 import QtWidgets as qtw
from PySide6 import QtMultimedia as qtm
from PySide6 import QtMultimediaWidgets as qtmw
app = qtw.QApplication()
view = qtw.QGraphicsView()
scene = qtw.QGraphicsScene()
video_item = qtmw.QGraphicsVideoItem()
scene.addItem(video_item)
view.setScene(scene)
view.fitInView(video_item, qtc.Qt.AspectRatioMode.KeepAspectRatio)
media_player = qtm.QMediaPlayer()
media_player.setVideoOutput(video_item)
media_player.setSource("video_file")
media_player.mediaStatusChanged.connect(media_player.play)
view.show()
app.exec()
This is what it looks like in a 960/1080-ish window:
Related
I'm trying to create a floating, layout-less widget but it doesn't seem to work with a QVideoWidget as it's parent?
Working MRE:
from PySide6 import QtWidgets as qtw
app = qtw.QApplication()
w1 = qtw.QWidget()
w2 = qtw.QWidget(w1)
w2.setStyleSheet("background-color: red")
w1.show()
w2.show()
app.exec()
Not working MRE:
from PySide6 import QtMultimediaWidgets as qtmw
from PySide6 import QtWidgets as qtw
app = qtw.QApplication()
w1 = qtmw.QVideoWidget()
w2 = qtw.QWidget(w1)
w2.setStyleSheet("background-color: red")
w1.show()
w2.show()
app.exec()
The code is supposed to overlay a red QWidget over the QWidget/QVideoWidget but the red QWidget is shown only when the parent is a QWidget, and not when it's a QVideoWidget, why could that be?
I tried this but this doesn't track the mouse movement unless a button is pressed:
from PySide6 import QtWidgets as qtw
from PySide6 import QtMultimediaWidgets as qtmw
app = qtw.QApplication()
vw = qtmw.QVideoWidget()
vw.setMouseTracking(True)
vw.mouseMoveEvent = lambda *x: print(1)
vw.show()
app.exec()
On other widgets, I would setMouseTracking(True) for the .viewport(), but it doesn't look like QVideoWidget has a viewport.
I want to add spaces between the widgets, dynamically, so that, as i resize the window, the widgets get their gaps adjusted accordingly, so that the widgets will be evenly spread over the available window space.
#!/usr/bin/python3
import sys
import random
try:
from PySide6 import QtCore, QtWidgets
except ModuleNotFoundError:
from PySide2 import QtCore, QtWidgets
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.layout = QtWidgets.QVBoxLayout(self)
for i in range(0, 10):
self.text = QtWidgets.QLabel("Hello World",
alignment=QtCore.Qt.AlignCenter,
styleSheet = f'''
background-color: '#999999';
color : '#000000';
'''
)
self.layout.addWidget(self.text)
self.layout.addStretch()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
widget = MyWidget()
widget.resize(800, 600)
widget.show()
sys.exit(app.exec_())
If you set labels' vertical size policy to QtWidgets.QSizePolicy.Maximum or QtWidgets.QSizePolicy.Fixed and remove self.layout.addStretch() you'll get evenly spread stretch.
self.text.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
Alternatively you can add self.layout.addStretch() after every label to achieve same thing.
In pyqtgraph, Docks can be torn out of the DockArea by dragging or double clicking. The popups use a default icon. I would like to define my own icon. In the code below I set the application window. The same code has no effect on the dock, though there is no error message.
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout
from pyqtgraph.dockarea import Dock, DockArea
from PyQt5.QtGui import QIcon
class Foo(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowIcon(QIcon('direction'))
lay = QVBoxLayout(self)
da = DockArea()
d = Dock("Dock")
d.setWindowIcon(QIcon('direction')) # no effect
da.addDock(d)
lay.addWidget(da)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
I looked in the source code of Dock and DockArea of pyqtgraph and found out I had to overwrite floatDock function.
I created a function
def floatDockPatched(self, dock):
"""Removes *dock* from this DockArea and places it in a new window."""
area = self.addTempArea()
area.win.resize(dock.size())
area.win.setWindowIcon(QIcon("res/haip.png"))
area.win.setWindowTitle(dock.label.text())
area.moveDock(dock, 'top', None)
and assigned it to the class as overwrite
DockArea.floatDock = floatDockPatched
I am experimenting with Qt 5 QScrollArea (in Python and PyQt, but I believe the question applies just as well in C++ Qt).
The Qt documentation for QScrollArea::widgetResizable says that "If this property is set to false (the default), the scroll area honors the size of its widget." By "its widget", I assume it means the widget being viewed in the scroll area.
However, in the program below I show an image label inside the scroll area, but the scroll area does not seem to "honor the size of its widget", because the image is partly hidden from the start.
The documentation also says "Regardless of this property, you can programmatically resize the widget using widget()->resize(), and the scroll area will automatically adjust itself to the new size." However, I do invoke resize for the viewed widget, but nothing happens.
The documentation also says "If this property is set to true, the scroll area will automatically resize the widget in order to avoid scroll bars where they can be avoided, or to take advantage of extra space." However, I don't see any resizing, even though if the widget were resized then it would be possible to avoid the scroll bars.
This is what I see whether I set the property to True or False, and whether I invoke widget().resize() or not:
Clearly I must be missing something quite fundamental here; what is it?
Edit: the main purpose of the question is understanding how widgetResizable works and what it does. Fitting the image into the window is a secondary goal.
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QImage, QPalette, QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QScrollArea
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
image = QImage("happyguy.png")
imageLabel = QLabel()
imageLabel.setPixmap(QPixmap.fromImage(image))
scrollArea = QScrollArea()
scrollArea.setBackgroundRole(QPalette.Dark)
scrollArea.setWidget(imageLabel)
scrollArea.setWidgetResizable(True)
scrollArea.widget().resize(QSize(10, 10))
self.setCentralWidget(scrollArea)
app = QApplication([])
w = MainWindow()
w.show()
app.exec_()
And here's the happyguy.pgn file:
scrollArea.setWidgetResizable(True) give the resize control of imageLabel to scrollArea. So the next line scrollArea.widget().resize(QSize(10, 10)) will be overrode by system.
A solution worked on windows (resize main window to fit image size).
from PyQt5.QtGui import QImage, QPalette, QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QScrollArea, QFrame
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
image = QImage("happyguy.png")
imageLabel = QLabel()
imageLabel.setPixmap(QPixmap.fromImage(image))
scrollArea = QScrollArea()
scrollArea.setFrameShape(QFrame.NoFrame)
scrollArea.setBackgroundRole(QPalette.Dark)
scrollArea.setWidget(imageLabel)
self.setCentralWidget(scrollArea)
self.resize(image.size())
app = QApplication([])
w = MainWindow()
w.show()
app.exec_()
Or use QScrollArea.setMinimumSize
from PyQt5.QtGui import QImage, QPalette, QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QScrollArea, QFrame
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
image = QImage("happyguy.png")
imageLabel = QLabel()
imageLabel.setPixmap(QPixmap.fromImage(image))
scrollArea = QScrollArea()
scrollArea.setFrameShape(QFrame.NoFrame)
scrollArea.setBackgroundRole(QPalette.Dark)
scrollArea.setWidget(imageLabel)
scrollArea.setMinimumSize(image.size())
self.setCentralWidget(scrollArea)
app = QApplication([])
w = MainWindow()
w.show()
app.exec_()
Resizable IS NOT Scrollable ...