Reputation: 91
I want to play a media on dropEvent
of a QVideoWidget
. I know the playing part, my problem is QVideoWidget not receiving dropEvent like other widgets.
I'm wonder this is a bug or I am missing something.
Everything is ok and all three events getting called:
import sys
from PySide6.QtCore import QSize
from PySide6.QtMultimediaWidgets import QVideoWidget
from PySide6.QtWidgets import QApplication, QWidget
class MyWidget(QWidget):
def __init__(self,*args):
super().__init__(*args)
self.setAcceptDrops(True)
self.setMinimumSize(QSize(600,400))
def dragEnterEvent(self, event):
print(event)
event.accept()
def dragMoveEvent(self, event):
print(event)
event.accept()
def dropEvent(self, event):
print(event)
if __name__ == "__main__":
app = QApplication([])
widget = MyWidget()
widget.show()
sys.exit(app.exec())
But when I use same code with a QVideoWidget
, dropEvent
not getting called:
import sys
from PySide6.QtCore import QSize
from PySide6.QtMultimediaWidgets import QVideoWidget
from PySide6.QtWidgets import QApplication, QWidget
class MyWidget(QVideoWidget):
def __init__(self,*args):
super().__init__(*args)
self.setAcceptDrops(True)
self.setMinimumSize(QSize(600,400))
def dragEnterEvent(self, event):
print(event)
event.accept()
def dragMoveEvent(self, event):
print(event)
event.accept()
def dropEvent(self, event):
print(event)
if __name__ == "__main__":
app = QApplication([])
widget = MyWidget()
widget.show()
sys.exit(app.exec())
P.S : I don't know why but in the last code dropEvent
works on title bar!
I can upload a GIF if needed.
Upvotes: 1
Views: 377
Reputation: 11
Thanks, that saved my day! I ran in to same issue and wrote a Qt bug report (haven't found any so far: https://bugreports.qt.io/browse/QTBUG-107668). In C++, this looks like this:
VideoWidget::VideoWidget(QWidget *parent) : QVideoWidget(parent)
{
QObject *c = findChild<QWidget*>();
c->installEventFilter(this);
}
bool VideoWidget::eventFilter(QObject *obj, QEvent *ev)
{
QObject *c = findChild<QWidget*>();
if(obj == c){
if(ev->type() == QEvent::DragEnter){
qDebug()<<"Drag Enter";
return true;
}
else if(ev->type() == QEvent::DragMove){
//qDebug()<<"Drag Move";
return true;
}
else if(ev->type() == QEvent::Drop){
qDebug()<<"Drop";
return true;
}
}
return QVideoWidget::eventFilter(obj, ev);
}
Upvotes: 1
Reputation: 243897
You have discovered a bug, QVideoWidget in Qt6 uses a QWindow to speed up painting and this is added as a child of the QVideoWidget so the drag and drop event is not propagated to the parent. A workaround is to use an eventfilter to listen to the event.
import sys
from PySide6.QtCore import QSize, QEvent
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtMultimediaWidgets import QVideoWidget
class MyWidget(QVideoWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumSize(QSize(600, 400))
self.window_child.installEventFilter(self)
@property
def window_child(self):
child = self.findChild(QWidget)
if child.metaObject().className() == "QWindowContainer":
return child
def eventFilter(self, obj, event):
if obj is self.window_child:
if event.type() == QEvent.Type.DragEnter:
print("dragEnterEvent:", event)
elif event.type() == QEvent.Type.DragMove:
print("dragMoveEvent:", event)
elif event.type() == QEvent.Type.Drop:
print("dropEvent", event)
return super().eventFilter(obj, event)
if __name__ == "__main__":
app = QApplication([])
widget = MyWidget()
widget.show()
sys.exit(app.exec())
Upvotes: 3