【问题标题】:"Python has stopped working" error when instantiating subclass of QStyledItemDelegate twice两次实例化 QStyledItemDelegate 的子类时出现“Python 已停止工作”错误
【发布时间】:2021-09-24 13:26:36
【问题描述】:

我有以下代码来对齐 QTableWidget 列的文本。

import sys

from PyQt5           import QtWidgets, QtCore
from PyQt5.QtCore    import Qt
from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QStyledItemDelegate

class AlignRightDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(AlignRightDelegate, self).initStyleOption(option, index)
        option.displayAlignment = Qt.AlignRight

class Table(QTableWidget):
    def __init__(self, data, alignColumns = 1, *args):
        QTableWidget.__init__(self, *args)
        self.setRowCount(len(data))
        self.setColumnCount(3)

        self.setData(data)
        self.resizeColumnsToContents()

        for colIndex in range(1, 1 + alignColumns):
            print("Align Column [", colIndex, "]", sep="")
            self.setItemDelegateForColumn(colIndex, AlignRightDelegate())

    def setData(self, data): 
        horizontalHeaders = []
        for m, rowContent in enumerate(data):
            for n, cellContent in enumerate(data[m]):
                if (m == 0):
                    horizontalHeaders.append(cellContent)
                else:
                    self.setItem(m - 1, n, QTableWidgetItem(cellContent))
        self.setHorizontalHeaderLabels(horizontalHeaders)

if __name__ == "__main__":
    data = [["col1", "col2", "col3"],
            [   "1",   "1", "a"],
            [  "-1",   "2", "b"], 
            [   "0",   "3", "c"]]
    print("python QTableWidgetAlignRight.py[ <AlignColumnCount=1]")
    app = QApplication(sys.argv)
    table = Table(data, int(sys.argv[1])) if (len(sys.argv) > 1) else Table(data)
    table.show()
    sys.exit(app.exec_())

如果我使用python QTableWidgetAlignRight.py 1 执行上面的代码,它有点工作,它应该如下所示,col2 与右侧对齐但显然与也顶

但是,当我使用 python QTableWidgetAlignRight.py 2 执行相同的代码时,我尝试将 2 列向右对齐,我遇到了 Python has stopped working error。以下截图其实是在我的日文Windows OS(Win 10 Pro 20H2 (OS Build 19402.1165))

但是我在网上搜索了相同的英文错误消息,我发现了一个屏幕截图,尽管不是由于我上面的代码(从这个页面挖掘:Python has stopped working)。

那么对齐我的 QTableWidget 的 2 列的正确方法是什么(没有错误并且没有垂直对齐到顶部)?这也是 PyQt5 中的一个错误吗?

为了您的信息,我正在使用以下内容:Python 3.7.6conda 4.8.2pyqt 5.9.2 py37h6538335_2。对于列对齐,我查看了这个以供参考:How to align all items in a column to center in QTableWidget

【问题讨论】:

    标签: python pyqt5


    【解决方案1】:

    由于 python 和 PyQt 保持对对象的引用的方式,只有 one unparentedunreferenced 委托可以理论上为每个视图设置。

    但是,虽然可以像这样设置一个委托,但不应该这样做:委托应该始终具有持久引用或有效的父级,因为视图没有 获得委托的所有权(请参阅所有 setItemDelegate* 函数的文档)。

    另外,考虑到您对多个列使用相同的委托,创建多个列是没有意义的。

        self.alignDelegate = AlignRightDelegate(self)
        for colIndex in range(1, 1 + alignColumns):
            print("Align Column [", colIndex, "]", sep="")
            self.setItemDelegateForColumn(colIndex, self.alignDelegate)
    

    请注意,您可以使用父参数 (self) 创建实例属性:

    self.alignDelegate = AlignRightDelegate()
    # or
    alignDelegate = AlignRightDelegate(self)
    

    不过,同时使用这两个不是问题,并且在处理 Qt 对象时指定父对象是一个不错的选择。
    在任何情况下,至少应始终使用上述方法之一。

    你得到一个错误的对齐方式,因为你只设置了水平对齐方式:使用option.displayAlignment = Qt.AlignRight | Qt.AlignVCenter

    【讨论】:

    • 第一段有错别字吗?就目前而言,这似乎是矛盾的。
    • @ekhumoro 也许我应该换个说法:我的意思是在 PyQt 中可以使用未引用的委托实例,但只有一个:只要它试图为相同的创建另一个查看,程序将冻结。因此,虽然它在技术上有效,但不应该这样做。
    • 所以它应该是“一个”而不是“一个”。但是,我仍然认为建议应该始终保持参考 - 特别是当文档声明 Qt 不拥有所有权时。说它“可以”在 PyQt 中完成表明它在某种意义上得到了明确的支持,而不仅仅是一个实现细节。
    • @ekhumoro 好点,再次。我已经更新了答案,我相信现在应该更清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2018-09-12
    • 2020-09-20
    相关资源
    最近更新 更多