You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5 QTableWidget多列对齐触发Python has stopped working报错

问题根因

  1. 文本垂直靠上:你覆写initStyleOption时直接将displayAlignment赋值为Qt.AlignRight,直接覆盖了原有属性里的垂直对齐配置,默认的垂直居中属性丢失,所以只有水平右对齐生效,垂直方向变为默认的顶部对齐。
  2. 程序崩溃:属于PyQt对象生命周期管理的常见问题,你在循环中创建的AlignRightDelegate是临时对象,没有被Python层持有引用,执行完setItemDelegateForColumn后会被Python垃圾回收,Qt层面仍持有已销毁对象的指针,后续访问触发野指针崩溃。单列时未触发属于巧合,多列创建多个临时对象时GC触发概率大幅提升,所以必现崩溃,不属于PyQt的Bug。

修正方案

修改两处代码即可:

  1. 对齐属性设置时保留垂直居中,或者显式指定垂直对齐
  2. 将创建的delegate实例存到表格的实例属性中,避免被GC回收

修正后完整代码

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 = (option.displayAlignment & ~Qt.AlignHorizontal_Mask) | Qt.AlignRight | Qt.AlignVCenter

class Table(QTableWidget):
    def __init__(self, data, alignColumns = 1, *args):
        QTableWidget.__init__(self, *args)
        self.setRowCount(len(data))
        self.setColumnCount(3)
        # 新增列表持有delegate实例,避免被GC回收
        self.align_delegates = []

        self.setData(data)
        self.resizeColumnsToContents()

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

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

替代方案(无需自定义Delegate)

如果不需要统一控制整列的后续动态新增内容,可以直接在创建QTableWidgetItem时指定对齐属性,写法更简单,也不会有生命周期问题:

# 修改setData方法里的item创建逻辑
item = QTableWidgetItem(cellContent)
item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.setItem(m - 1, n, item)

内容的提问来源于stack exchange,提问作者mak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:27:03