Qt.py
Qt.py copied to clipboard
Table Drop Event and loadUi with PySide2
I am having this issue with loadUi with Pyside2 where I am not able to override a dropEvent in the following situation:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Qt.QtCompat import loadUi
from Qt.QtWidgets import QWidget, QApplication
import tempfile
import os
ui = b'''<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listWidget">
<property name="dragEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="tableWidget">
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DropOnly</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
'''
class Widget(QWidget):
def __init__(self):
super().__init__(parent=None)
with tempfile.NamedTemporaryFile("w+b", delete=False) as f:
f.write(ui)
loadUi(f.name, self)
os.unlink(f.name)
self.tableWidget.setRowCount(3)
self.tableWidget.setColumnCount(3)
self.tableWidget.dropEvent = self.tableDrop
for x in range(4):
self.listWidget.addItem("item" + str(x))
def tableDrop(self, event):
print('tableDrop', event)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
When we run this code using PySide2 we get unexpected (default) behaviour when we drag and drop an element from the list into the table below
$ QT_PREFERRED_BINDING=PySide2 python droptable.py
but when we run it using PyQt5 we catch the event in our assigned function.
$ QT_PREFERRED_BINDING=PyQt5 python droptable.py
tableDrop <PyQt5.QtGui.QDropEvent object at 0x7f37e0f93be0>
This looks like a gap in the shim, that can be looked into.
Can you please recommend a bindling agnostic way to load a .ui form containing an element whose dropEvent we want to override?
Look like a gap indeed. I'm not sure why it happens, does it happen with native PySide2? If so, might be worth reaching out to the PySide2 devs for a fix. If not, then the problem must reside in Qt.py. If you find anything, a pull-request would be great.
No it does not happen with native PySide2 meaning if I use pyside2uic to compile ui into py I can go back to catching dropEvents.
So there is one way around it for now.
FYI! I find similar behaviour with QtPy!