PyQt6 аварийно завершает работу при попытке редактировать ячейку в QTableWidget при использовании setCellWidget на Wayland

Обновлено: это исправлено в обновлении Qt 6.7.

Если я запущу приведенный ниже код, а затем попытаюсь отредактировать первую ячейку, дважды щелкнув или начав вводить текст, окно зависнет и закроется с выводом Segmentation fault (core dumped).

Это исправлено, если я отключу редактирование ячеек или вместо этого использую PyQt5.

Он не выйдет из строя, если я отключу переменную среды WAYLAND_DISPLAY, чтобы вместо этого заставить программу запускаться в Xwayland (или, по крайней мере, я так думаю), при этом выводится:

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

Хотя оно до сих пор работает.

Я хочу иметь возможность отображать изображение внутри ячейки таблицы. Я попытался сделать это, создав метку, установив ее растровое изображение в изображение, а затем используя table.setCellWidget, но затем столкнулся с этой проблемой.

Это похоже на ошибку PyQt6/Qt, но если это не так, есть ли способ исправить это без использования исправлений, показанных выше?

Вот мои версии PyQt6, если это имеет значение (я пробовал как установку с помощью pip, так и использование системных пакетов, предоставленных менеджером пакетов):

PyQt6      6.6.1
PyQt6-Qt6  6.6.3
PyQt6-sip  13.6.0

Код:

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()

Два файла журнала после включения ведения журнала, как упоминалось здесь: xwaylandВэйланд

PyQt почти наверняка не имеет к этому никакого отношения, и, вероятно, это ошибка Qt/Wayland. Событие мыши, вероятно, не обрабатывается должным образом, если оно частично игнорируется в дереве виджетов (QWidget и QLabel по умолчанию не принимают события мыши). Если можете, протестируйте его с помощью PySide6 и рассмотрите возможность сообщения об ошибке на bugreports.qt.io. Обратите внимание, что на самом деле более подходящим способом отображения изображений в представлениях элементов Qt является установка QPixmap в качестве Qt.ItemDataRole.DecorationRole элемента или использование пользовательского делегата элемента.

musicamante 08.04.2024 20:26

@musicamante все еще вылетает с PySide6. Я мог бы отправить отчет об ошибке. Использование Qt.ItemDataRole.DecorationRole элемента, похоже, работает, спасибо!

fieryhenry 08.04.2024 21:54
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обновлено: это исправлено в обновлении Qt 6.7.

Благодаря @musicamante мне удалось заставить изображение работать, используя вместо этого Qt.ItemDataRole.DecorationRole.

Новый код:

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()


Другие вопросы по теме