pythonpyqt6wayland

PyQt6 crashes when trying to edit a cell in a QTableWidget when using setCellWidget on Wayland


EDIT: This has been fixed in the Qt 6.7 update.

If I run the code below, and then try to edit the first cell, either by double-clicking or by beginning to type, the window freezes and closes with Segmentation fault (core dumped) as output.

This is fixed if I disable editing the cells or if PyQt5 is used instead.

It does not crash if I unset the WAYLAND_DISPLAY environment variable to force the program to run in Xwayland instead (or at least that's what I think it does), doing so prints:

Failed to create wl_display (Connection refused)
qt.qpa.plugin: Could not load the Qt platform plugin "wayland" in "" even though it was found.

Although it still works.

I want to be able to display an image inside of a cell in a table. I tried to do that by creating a label, setting its pixmap to the image and then using table.setCellWidget, but then I ran into this issue.

This seems like a PyQt6 / Qt bug but if it isn't, is there a way to fix this without using the fixes shown above?

Here are my PyQt6 versions if it matters (I have tried both installing with pip and using the system packages provided by the package manager):

PyQt6      6.6.1
PyQt6-Qt6  6.6.3
PyQt6-sip  13.6.0

Code:

from PyQt6 import QtWidgets


class Crash(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Crash")
        self.resize(800, 600)
        self.show()
        self.init_ui()

    def init_ui(self):
        self.table = QtWidgets.QTableWidget()
        self.setCentralWidget(self.table)

        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(["text", "widget"])

        self.table.insertRow(0)
        self.table.setItem(0, 0, QtWidgets.QTableWidgetItem("text"))

        widget = QtWidgets.QWidget()

        self.table.setCellWidget(0, 1, widget)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    window = Crash()
    app.exec()

The 2 log files after enabling logging as mentioned here: xwayland wayland


Solution

  • EDIT: This has been fixed in the Qt 6.7 update.

    Thanks to @musicamante, I managed to get an image to work using Qt.ItemDataRole.DecorationRole instead.

    New Code:

    from PyQt6 import QtWidgets, QtGui, QtCore
    
    
    class Crash(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Crash")
            self.resize(800, 600)
            self.show()
            self.init_ui()
    
        def init_ui(self):
            self.table = QtWidgets.QTableWidget()
            self.setCentralWidget(self.table)
    
            self.table.setColumnCount(2)
            self.table.setHorizontalHeaderLabels(["text", "widget"])
    
            self.table.insertRow(0)
            self.table.setItem(0, 0, QtWidgets.QTableWidgetItem("text"))
    
            # set img with Qt.ItemDataRole.DecorationRole instead
            img_path = "img.png"
            img = QtGui.QPixmap(img_path)
            item = QtWidgets.QTableWidgetItem()
            item.setData(QtCore.Qt.ItemDataRole.DecorationRole, img)
            self.table.setItem(0, 1, item)
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication([])
        window = Crash()
        app.exec()