I am working on a widget that needs to update itself when another widget it is matched with moves or is resized. Currently, I have the other widget do its own resizeEvent() and moveEvent() and inside that it emits a signal that my widget connects to.
However, I do not like this setup. Say later on I want to have my other widget do a different thing with its resizeEvent().
Is there a way for widget A (from widget A only) to be informed when widget B's resizeEvent() or moveEvent() is fired?
You could create a Helper class that is responsible for monitoring, so you do not need to overwrite the classes.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Helper(QObject):
def setWidgets(self, emmiter, receiver):
emmiter.installEventFilter(self)
self.emmiter = emmiter
self.receiver = receiver
def eventFilter(self, obj, event):
if obj == self.emmiter:
if event.type() == QEvent.Resize:
self.receiver.resize(self.emmiter.size())
elif event.type() == QEvent.Move:
self.receiver.move(event.pos())
return QObject.eventFilter(self, obj, event)
if __name__ == '__main__':
app = QApplication(sys.argv)
helper = Helper()
w1 = QWidget()
w1.setWindowTitle("emmiter")
w2 = QWidget()
helper.setWidgets(w1, w2)
w1.show()
w2.show()
sys.exit(app.exec_())
Related
Hopefully I am following the guidelines correctly here with my first question. I am trying to create a GUI with the MVC structure. I am having difficulty with understanding why my signals are not always being picked up by the controller. I know that there is just something simple that I'm missing. I'm attaching code from a simple calculator which I used as a guide. I removed most of the features to simplify this as much as possible. It is now only 3 of the original buttons and my own button. For debugging, I just have the value on the button printed out when you press it.
import sys
# Import QApplication and the required widgets from PyQt5.QtWidgets
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QMainWindow
from PySide2.QtWidgets import QWidget
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QGridLayout
from PySide2.QtWidgets import QLineEdit
from PySide2.QtWidgets import QPushButton
from PySide2.QtWidgets import QVBoxLayout
from functools import partial
ERROR_MSG = 'ERROR'
# Create a subclass of QMainWindow to setup the calculator's GUI
class PyCalcUi(QMainWindow):
"""PyCalc's View (GUI)."""
def __init__(self):
"""View initializer."""
super().__init__()
# Set some main window's properties
self.setWindowTitle('PyCalc')
self.setFixedSize(235, 235)
# Set the central widget and the general layout
self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)
# Create the display and the buttons
self._createDisplay()
self._createButtons()
def _createDisplay(self):
"""Create the display."""
# Create the display widget
self.display = QLineEdit()
# Set some display's properties
self.display.setFixedHeight(35)
self.display.setAlignment(Qt.AlignRight)
self.display.setReadOnly(True)
# Add the display to the general layout
self.generalLayout.addWidget(self.display)
def _createButtons(self):
"""Create the buttons."""
self.buttons = {}
buttonsLayout = QGridLayout()
# Button text | position on the QGridLayout
buttons = {'7': (0, 0),
'8': (0, 1),
'9': (0, 2),
}
# Create the buttons and add them to the grid layout
for btnText, pos in buttons.items():
self.buttons[btnText] = QPushButton(btnText)
self.buttons[btnText].setFixedSize(40, 40)
buttonsLayout.addWidget(self.buttons[btnText], pos[0], pos[1])
self.mybutton = QPushButton("5")
buttonsLayout.addWidget(self.mybutton,1,0)
# Add buttonsLayout to the general layout
self.generalLayout.addLayout(buttonsLayout)
# Create a Controller class to connect the GUI and the model
class PyCalcCtrl:
"""PyCalc Controller class."""
def __init__(self, model, view):
"""Controller initializer."""
self._evaluate = model
self._view = view
# Connect signals and slots
self._connectSignals()
def _printthis(self):
print("Hi")
def _printthat(self, buttonvalue):
print(buttonvalue)
def _connectSignals(self):
"""Connect signals and slots."""
self._view.mybutton.clicked.connect(self._printthis)
for btnText, btn in self._view.buttons.items():
btn.clicked.connect(partial(self._printthat, btnText))
# Create a Model to handle the calculator's operation
def evaluateExpression(expression):
"""Evaluate an expression."""
try:
result = str(eval(expression, {}, {}))
except Exception:
result = ERROR_MSG
return result
# Client code
def main():
"""Main function."""
# Create an instance of QApplication if it doesn't exist
pycalc = QApplication.instance()
if pycalc is None:
pycalc = QApplication(sys.argv)
# Show the calculator's GUI
view = PyCalcUi()
view.show()
# Create instances of the model and the controller
model = evaluateExpression
PyCalcCtrl(model=model, view=view)
# Execute the calculator's main loop
sys.exit(pycalc.exec_())
if __name__ == '__main__':
main()
This set of code works, BUT if I comment out the
for btnText, btn in self._view.buttons.items():
btn.clicked.connect(partial(self._printthat, btnText))
The self._view.mybutton.clicked.connect(self._printthis) will no longer work.
What is the btn.clicked.connect(partial(self._printthat, btnText)) line doing which is allowing any other signal I put in def _connectSignals(self): to work. What aspect of that line is achieving something that the mybutton signal isn't doing?
The problem is caused because the PyCalcCtrl object is not assigned to a variable so it will be destroyed and therefore the "_printthis" method will not be accessible. On the other hand, when functools.partial is used then the object of the PyCalcCtrl class is assigned to the scope of that function, that's why it works.
The solution is to assign the PyCalcCtrl object to a variable:
ctrl = PyCalcCtrl(model=model, view=view)
In my QMainWindow i have a button which opens a new QDialog in the bottom right monitorcorner with a successmessage when i click it.
Now, if i move the QMainWindow to another monitor (i have 3 monitor) and click the button the successmessage popup appears in the monitor where the QMainWindow was opened. What i want is that the popup message appears in the monitor where my QMainWindow actually is. So if i move the QMainWindow to Monitor 1 and click the button, the successpopup should opens in monitor 1. If the QMainWindow is in monitor 2, the successpopup should open in monitor 2 an same for monitor 3.
with
screenNumber = QDesktopWidget().screenNumber(self)
i can read the screennumber where the mainwindow is. and this works fine. Evertime i click the button i read out the screennumber. But i don't found a way, to set the screennumber to my notification.
Any ideas?
Edit:
maybe it helps if i show my notify class
notes.py
from UIs.UI_notify import Ui_Notification
from PyQt5.QtWidgets import QDialog, QApplication, QDesktopWidget
from PyQt5 import QtCore
from PyQt5.QtCore import QRect, QPropertyAnimation, QTimer
import sys
class icon():
checked = "check-circle"
alert = "times-circle"
question = "question-circle"
class notify(QDialog, Ui_Notification):
def __init__(self, parent=None):
super(notify,self).__init__(parent)
self.setupUi(self)
self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground)
## Some helping stuff
############################################################
parent_sSize = QDesktopWidget().screenGeometry(parent)
parent_screenNumber = QDesktopWidget().screenNumber(parent)
sSize = QDesktopWidget().screenGeometry()
screenNumber = QDesktopWidget().screenNumber()
print("notification ScreenNumber = " + str(screenNumber))
print(sSize.width())
print(sSize.height())
print("Parents ScreenNumber = " + str(parent_screenNumber))
print(parent_sSize.width())
print(parent_sSize.height())
self.Note_Exit.clicked.connect(self.close)
## ScreenSize from parent
############################################################
self.hidedPos = QRect(parent_sSize.width()-self.width()-10,
parent_sSize.height()-self.height()+200,
self.frameGeometry().width(),
self.frameGeometry().height())
self.showPos = QRect(parent_sSize.width()-self.width()-10,
parent_sSize.height()-self.height()-50,
self.frameGeometry().width(),
self.frameGeometry().height())
def setNote(self, icon=icon.checked, headline="Headline", text="Text"):
self.icon = icon
self.headline = headline
self.text = text
self.noty_Label_Icon.setText(self.icon)
self.noty_Label_Headline.setText(self.headline)
self.noty_Label_Text.setText(self.text)
self.setGeometry(self.hidedPos)
self.anim = QPropertyAnimation(self,b"geometry")
self.anim.setDuration(700)
self.anim.setEasingCurve(QtCore.QEasingCurve.OutBack)
self.anim.setEndValue(self.showPos)
self.anim.start()
self.notyTimer = QTimer()
self.notyTimer.singleShot(4000,self.hideNote)
def hideNote(self):
self.anim = QPropertyAnimation(self,b"geometry")
self.anim.setDuration(700)
self.anim.setEasingCurve(QtCore.QEasingCurve.InOutBack)
self.anim.setEndValue(self.hidedPos)
self.anim.start()
self.anim.finished.connect(self.close)
if __name__ == "__main__":
notes = QApplication(sys.argv)
dialog = notify()
dialog.show()
sys.exit(notes.exec())
You cannot use the size of the widget during its construction, as at that moment it has a default size (640x480 for top level widgets, 100x30 for widgets created with a parent, including dialogs): the only reliable option is to use the sizeHint() or ensure that the layout has been properly activated with adjustSize().
Then, you don't need the screen to get the target position, as the parent geometry will suffice, but you do need it for the start position, otherwise the dialog will "pop up" at an arbitrary point below the window. Note that QDesktopWidget is considered obsolete, and you should use QScreen instead.
Finally, since you might want to reuse the notification, the start position should be set when the popup is actually being shown, not before. The same goes for the position when hiding (in case the notification could be moved).
class Notify(QDialog, Ui_Notification):
def __init__(self, parent):
super().__init__(parent)
self.setupUi(self)
self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.showAnim = QPropertyAnimation(self, b'geometry')
self.showAnim.setDuration(700)
self.showAnim.setEasingCurve(QtCore.QEasingCurve.OutBack)
self.hideAnim = QPropertyAnimation(self, b'geometry')
self.hideAnim.setDuration(700)
self.hideAnim.setEasingCurve(QtCore.QEasingCurve.InOutBack)
self.hideTimer = QTimer(self, singleShot=True)
self.hideTimer.setInterval(4000)
self.hideTimer.timeout.connect(self.hideNote)
self.showAnim.finished.connect(self.hideTimer.start)
self.hideAnim.finished.connect(self.close)
def setNote(self, icon=icon.checked, headline="Headline", text="Text"):
self.icon = icon
self.headline = headline
self.text = text
self.noty_Label_Icon.setText(self.icon)
self.noty_Label_Headline.setText(self.headline)
self.noty_Label_Text.setText(self.text)
self.adjustSize() # important!
endRect = self.rect()
center = self.parent().geometry().center()
endRect.moveCenter(center)
screen = QApplication.screenAt(center)
startRect = QRect(endRect)
startRect.moveTop(screen.geometry().bottom())
self.setGeometry(startRect)
self.showAnim.setStartValue(startRect)
self.showAnim.setEndValue(endRect)
self.showAnim.start()
self.show()
def hideNote(self):
rect = self.geometry()
self.hideAnim.setStartValue(rect)
screen = QApplication.screenAt(rect.center())
rect.moveTop(screen.geometry().bottom())
self.hideAnim.setEndValue(rect)
self.hideAnim.start()
if __name__ == "__main__":
notes = QApplication(sys.argv)
notes.setStyle('fusion')
w = QMainWindow()
b = QPushButton('click!')
w.setCentralWidget(b)
w.show()
notify = Notify(w)
b.clicked.connect(lambda: notify.setNote())
sys.exit(notes.exec())
Be aware that if you're going to create the popup every time, you should also set the WA_DeleteOnClose attribute in order to destroy it when closed, otherwise it will be kept in memory.
Note: QTimer.singleShot() is a static function, creating an instance of QTimer to use it is pointless, as that instance won't be used and a new QTimer would be created anyway.
Thank you.
In the meantime i found a solution which works for me.
Look a little dirty but works.
could you tell me, whats the difference between my code an yours?
Why should i use your code, except the fact that you are a better programmer ;-)
I set the WA_DeleteOnClose Attribute.
Good to know that. Thanks
notes.py
from UIs.UI_notify import Ui_Notification
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5 import QtCore
from PyQt5.QtCore import QRect, QPropertyAnimation, QTimer
import sys
class icon():
checked = "check-circle"
alert = "times-circle"
question = "question-circle"
clock = "clock"
class notify(QDialog, Ui_Notification):
def __init__(self, parent=None):
super(notify,self).__init__(parent)
self.setupUi(self)
self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose)
self.setWindowModality(QtCore.Qt.NonModal)
self.Note_Exit.clicked.connect(self.close)
self.parent_h = self.parent().geometry().height()
self.parent_w = self.parent().geometry().width()
self.parent_x = self.parent().geometry().x()
self.parent_y = self.parent().geometry().y()
self.dialog_w = self.width()
self.dialog_h = self.height()
self.setGeometry(self.parent_x+self.parent_w-self.dialog_w-10, self.parent_y+self.parent_h-self.dialog_h+120, self.dialog_w, self.dialog_h)
## ScreenSize from parent
############################################################
def setNote(self, icon=icon.checked, headline="Headline", text="Text"):
self.icon = icon
self.headline = headline
self.text = text
self.noty_Label_Icon.setText(self.icon)
self.noty_Label_Headline.setText(self.headline)
self.noty_Label_Text.setText(self.text)
self.anim = QPropertyAnimation(self,b"geometry")
self.anim.setDuration(700)
self.anim.setEasingCurve(QtCore.QEasingCurve.OutBack)
self.anim.setEndValue(QRect(self.parent_x+self.parent_w-self.dialog_w-10, self.parent_y+self.parent_h-self.dialog_h-20, self.dialog_w, self.dialog_h))
self.anim.start()
self.notyTimer = QTimer()
self.notyTimer.singleShot(4000,self.hideNote)
def hideNote(self):
self.anim = QPropertyAnimation(self,b"geometry")
self.anim.setDuration(700)
self.anim.setEasingCurve(QtCore.QEasingCurve.InOutBack)
self.anim.setEndValue(QRect(self.parent_x+self.parent_w-self.dialog_w-10, self.parent_y+self.parent_h-self.dialog_h+120, self.dialog_w, self.dialog_h))
self.anim.start()
self.anim.finished.connect(self.close)
if __name__ == "__main__":
notes = QApplication(sys.argv)
dialog = notify()
dialog.show()
sys.exit(notes.exec())
I want to make a simple browser GUI for learning purposes with PyQt5. A function that I want is to have in the status bar a text "Online". If the user clicks somewhere else from the browser and the application loses focus, a message will appear in the status bar indicating that, and after a few seconds the browser will change the url to google.
If I run the following code everything works fine as expected, when app loses focus it navigates to google. However, the message "Application lost focus ..." doesn't appear in the statusbar. It simply skips that line. If I remove the seturl and time.sleep line, the script will change the text as expected.
Why is it skipping that line? (Line 55)
import sys
import time
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QFrame ,QMainWindow, QLabel
from PyQt5.QtWebEngineWidgets import *
class VLine(QFrame):
# a simple VLine, like the one you get from designer
def __init__(self):
super(VLine, self).__init__()
self.setFrameShape(self.VLine|self.Sunken)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setFocus()
app.focusChanged.connect(self.on_focusChanged)
self.browser = QWebEngineView()
self.browser.setContextMenuPolicy(Qt.PreventContextMenu)
self.browser.setUrl(QUrl('http://stackoverflow.com'))
self.setCentralWidget(self.browser)
self.showMaximized()
self.date = QDate.currentDate()
font = QFont('Arial', 16, QFont.Bold)
self.statusBar().setFont(font)
timer = QTimer(self)
timer.timeout.connect(self.showTime)
timer.start(1000)
self.lbl1 = QLabel(self)
self.lbl1.setStyleSheet('border: 0; color: red;')
self.lbl1.setFont(font)
self.statusBar().reformat()
self.statusBar().setStyleSheet('border: 0; background-color: #FFF8DC;')
self.statusBar().setStyleSheet("QStatusBar::item {border: none;}")
self.statusBar().addPermanentWidget(VLine()) # <---
self.statusBar().addPermanentWidget(self.lbl1)
self.statusBar().addPermanentWidget(VLine())
def showTime(self):
current_time = QTime.currentTime()
label_time = current_time.toString('hh:mm:ss')
self.statusBar().showMessage('Time: ' + label_time + ' || Date: ' + self.date.toString('dd.MM.yyyy'))
def on_focusChanged(self):
if self.isActiveWindow() == False:
print(f"\nwindow is the active window: {self.isActiveWindow()}")
self.lbl1.setText('Application lost focus. Returning to Google in 5 seconds')
time.sleep(5)
self.browser.setUrl(QUrl('http://google.com'))
self.lbl1.setText('Online')
else:
print(f"window is the active window: {self.isActiveWindow()}")
self.lbl1.setText('Online')
app = QApplication(sys.argv)
QApplication.setApplicationName('Browser')
window = MainWindow()
app.exec_()
You are confusing how the focusChanged signal works: it emits a signal regarding the focus changes within the program.
What you need is to override the changeEvent of the window and intercept an ActivationChange event type.
class MainWindow(QMainWindow):
# ...
def changeEvent(self, event):
if event.type() == event.ActivationChange:
# ...
That said, NEVER put a blocking function within the main thread.
Remove the time.sleep and never think about using it again for this kind of things.
Add a function for that redirect, and create a QTimer that you can start when losing focus (and stop if regaining it again before the timeout).
class MainWindow(QMainWindow):
def __init__(self):
# ...
self.focusLostTimer = QTimer(
interval=5000, singleShot=True, timeout=self.focusRedirect)
def focusRedirect(self):
self.browser.setUrl(QUrl('http://google.com'))
def changeEvent(self, event):
if event.type() == event.ActivationChange:
if not self.isActiveWindow():
self.focusLostTimer.start()
else:
self.focusLostTimer.stop()
Is there a simple way to check if the up or down button of a QT spinbox is pressed? I've seen this in a forum on QT but don't know how to deconstruct it or is far complex for me to understand and I'm coding in PyQT5.
void MySpinBox::mousePressEvent(QMouseEvent* event)
QSpinBox::mousePressEvent(event);
QStyleOptionSpinBox opt;
this->initStyleOption(&opt);
if( this->style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxUp).contains(event->pos()) )
// UP BUTTON PRESSED
else if( this->style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxDown).contains(event->pos()) )
//DOWN BUTTON PRESSED
Also I have this 2 variables that contain the spinbox value
version_spinValue = self.ui.version_sbox.value()
work_spinValue = self.ui.work_sbox.value()
All I want to do is when the version value spinbox up button is pressed, the work spinbox value resets to 1, and when it goes down, it just do nothing (or just print a simple text that the down button is pressed).
You have to use the hitTestComplexControl() method to know which element was clicked:
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QSpinBox, QStyle, QStyleOptionSpinBox
class SpinBox(QSpinBox):
upClicked = pyqtSignal()
downClicked = pyqtSignal()
def mousePressEvent(self, event):
super().mousePressEvent(event)
opt = QStyleOptionSpinBox()
self.initStyleOption(opt)
control = self.style().hitTestComplexControl(
QStyle.CC_SpinBox, opt, event.pos(), self
)
if control == QStyle.SC_SpinBoxUp:
self.upClicked.emit()
elif control == QStyle.SC_SpinBoxDown:
self.downClicked.emit()
def main():
import sys
app = QApplication(sys.argv)
w = SpinBox()
w.upClicked.connect(lambda: print("up"))
w.downClicked.connect(lambda: print("down"))
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I am trying to use QMediaPlayer to create a.. media player. I want to have an ability to rewind videos on press of a button.
But setting a negative playbackRate via QMediaPlayer.setPlaybackRate doesn't seem to put video on rewind. It just keeps playing forward.
I don't want to change the position of the video, I want the video to play at negative speed. Through some logic of mine, setting playbackRate to a negative value would make the video play in reverse. But that just doesn't happen. If you can't understand me clearly, here is a video of what the playback should look like.
Here is some barebones code to reproduce the problem:
import sys
from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication
class VideoWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
videoWidget = QVideoWidget()
self.setCentralWidget(videoWidget)
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.mediaPlayer.setVideoOutput(videoWidget)
self.mediaPlayer.setMedia(
QMediaContent(QUrl.fromLocalFile(r"<some video file>.mp4"))
)
self.mediaPlayer.play()
app.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.KeyPress:
key = event.key()
if key == Qt.Key_A:
self.mediaPlayer.setPlaybackRate(1.0)
elif key == Qt.Key_Y:
self.mediaPlayer.setPlaybackRate(-1.0) # This doesn't work! :(
return super().eventFilter(source, event)
def closeEvent(self, event):
self.mediaPlayer.setMedia(QMediaContent())
if __name__ == '__main__':
app = QApplication(sys.argv)
player = VideoWindow()
player.resize(640, 480)
player.show()
exitCode = app.exec_()
sys.exit(exitCode)
I tried searching for a solution, but I got nothing more than what documentation says (emphasis mine):
Values less than zero can be set and indicate the media will rewind at
the multiplier of the standard pace.
However, I am not seeing this effect.
I did notice this:
Not all playback services support change of the playback rate.
Is it possible that I can't rewind an mp4? Perhaps I need to install / change something?
QMediaPlayer.playbackRate property holds the playback rate of the current media.
This value is a multiplier applied to the media's standard play rate.
Press the Key_A, Key_Z, Key_Y keys to see how it works.
If you want to rewind the video, you should use QMediaPlayer.position property, which holds the playback position of the current media.
The value is the current playback position, expressed in milliseconds since the beginning of the media.
Press the Key_M, Key_P keys to see how it works.
import sys
from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication
class VideoWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
videoWidget = QVideoWidget()
self.setCentralWidget(videoWidget)
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.mediaPlayer.setVideoOutput(videoWidget)
self.mediaPlayer.setMedia(
QMediaContent(QUrl.fromLocalFile(r"<some video file>.mp4"))
)
self.mediaPlayer.play()
app.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QEvent.KeyPress:
key = event.key()
# It Playback Rate !
if key == Qt.Key_A:
#self.mediaPlayer.setPlaybackRate(1.0)
self.mediaPlayer.setPlaybackRate(1.5)
elif key == Qt.Key_Z:
self.mediaPlayer.setPlaybackRate(0.8)
elif key == Qt.Key_Y:
self.mediaPlayer.setPlaybackRate(1.0)
# setPosition(int), argument is in milliseconds.
elif key == Qt.Key_M:
self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000)
elif key == Qt.Key_P:
self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000)
return super().eventFilter(source, event)
def closeEvent(self, event):
self.mediaPlayer.setMedia(QMediaContent())
if __name__ == '__main__':
app = QApplication(sys.argv)
player = VideoWindow()
player.resize(640, 480)
player.show()
exitCode = app.exec_()
sys.exit(exitCode)