Segmentation fault on Mac OS during drag & drop
-
Hi,
I found that replacing a widget while a drag is happening can cause a segmentation fault on Mac OS (doesn't happen on my Windows machine). I am replacing it from the parent's widget dragEnterEvent.
I am using PyQt4 4.9.6 with Qt 4.8.3.
Below is an example program that shows the issue; dragging something from the list to the MyWidget on the right will cause a segmentation fault on Mac OS... Even though the child widget shouldn't be concerned by the drag and drop (only the parent accepts and handles it).
I can probably translate it to C++ if needed...
@import sys
from PyQt4 import QtCore, QtGui
class Widget1(QtGui.QWidget):
def init(self):
QtGui.QWidget.init(self)
# If this line is left commented out (which I need it to be), this
# program will crash on Mac OS
#self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
self.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding,
QtGui.QSizePolicy.MinimumExpanding)def sizeHint(self): return QtCore.QSize(100, 100) def paintEvent(self, event): qp = QtGui.QPainter(self) qp.setPen(QtGui.QColor(0, 0, 191)) qp.drawText(0, 0, self.width(), self.height(), QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, "First widget, drag something here")
class Widget2(QtGui.QWidget):
def init(self):
QtGui.QWidget.init(self)
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
self.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding,
QtGui.QSizePolicy.MinimumExpanding)def sizeHint(self): return QtCore.QSize(100, 100) def paintEvent(self, event): qp = QtGui.QPainter(self) qp.setPen(QtGui.QColor(191, 0, 0)) qp.drawText(0, 0, self.width(), self.height(), QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, "Second widget, overlay")
class MyWidget(QtGui.QWidget):
def init(self):
QtGui.QWidget.init(self)
self.setAcceptDrops(True)self._scrollarea = QtGui.QScrollArea() layout = QtGui.QVBoxLayout() layout.addWidget(self._scrollarea) self.setLayout(layout) self._inner_widget = Widget1() self._scrollarea.setWidget(self._inner_widget) def _set_widget(self, widget): self._inner_widget.setParent(None) self._inner_widget.deleteLater() self._inner_widget = widget self._scrollarea.setWidget(widget) widget.show() def dragEnterEvent(self, event): self._set_widget(Widget2()) event.accept() def dragLeaveEvent(self, event): self._set_widget(Widget1()) def dropEvent(self, event): self._set_widget(Widget1()) event.accept()
app = QtGui.QApplication(sys.argv)
listWidget = QtGui.QListWidget()
listWidget.setDragEnabled(True)
listWidget.setDragDropMode(QtGui.QAbstractItemView.DragOnly)
listWidget.addItem("An item")
listWidget.addItem("Other item")window = QtGui.QWidget()
layout = QtGui.QHBoxLayout()
layout.addWidget(listWidget)
layout.addWidget(MyWidget())
window.setLayout(layout)window.show()
app.exec_()@Is this a bug in Qt? How can I get this to work? (I am thinking about making both widgets TransparentForMouseEvents and forwarding manually the mouse events from MyWidget to Widget1... can I make this work?)
Thank you for your time