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

PySide6中QTableView如何本地化显示QSqlRelationalTableModel数据

解决QtSql.QSqlRelationalTableModel日期与金额本地化显示问题

方法一:重写QSqlRelationalTableModel的data方法

通过自定义模型子类,在数据提供阶段直接格式化日期和金额,确保所有使用该模型的视图都能应用统一格式。

1. 定义自定义模型类

from PySide6 import QtCore, QtSql

class CustomRelationalTableModel(QtSql.QSqlRelationalTableModel):
    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            # 处理日期列(对应索引1的"Datum"列)
            if index.column() == 1:
                raw_date = super().data(index, QtCore.Qt.DisplayRole)
                # 适配数据库中存储的日期类型(QDate或字符串)
                if isinstance(raw_date, QtCore.QDate):
                    return raw_date.toString("dd.MM.yyyy")
                elif isinstance(raw_date, str):
                    # 假设数据库存储为ISO格式字符串,可根据实际存储格式调整
                    q_date = QtCore.QDate.fromString(raw_date, QtCore.Qt.ISODate)
                    return q_date.toString("dd.MM.yyyy")
            
            # 处理金额列(对应索引2的"Betrag"列)
            elif index.column() == 2:
                raw_num = super().data(index, QtCore.Qt.DisplayRole)
                if isinstance(raw_num, (int, float)):
                    # 使用德语区本地化格式(千分位用点,小数位用逗号)
                    de_locale = QtCore.QLocale(QtCore.QLocale.German)
                    return de_locale.toString(raw_num, 'f', 2)
        
        # 其他角色和列直接调用父类逻辑
        return super().data(index, role)

2. 替换原模型为自定义模型

修改数据库模块的incomeViewData函数,将原QSqlRelationalTableModel替换为自定义模型:

def incomeViewData(self):
    """
    data model for income table
    """
    # 初始化自定义关系表模型
    self.model = CustomRelationalTableModel()
    self.model.setTable("income")
    
    # 保留原有的关联设置
    self.model.setRelation(3, QtSql.QSqlRelation("inc_category", "inc_cat_id", "inc_cat_name"))
    self.model.setRelation(4, QtSql.QSqlRelation("cycle", "cyc_id", "cycle_name"))
    self.model.setRelation(5, QtSql.QSqlRelation("var_fix", "var_id", "value"))
    
    # 表头设置保持不变
    self.model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
    self.model.setHeaderData(1, QtCore.Qt.Horizontal, "Datum")
    self.model.setHeaderData(2, QtCore.Qt.Horizontal, "Betrag")
    self.model.setHeaderData(3, QtCore.Qt.Horizontal, "Kategorie")
    self.model.setHeaderData(4, QtCore.Qt.Horizontal, "Turnus")
    self.model.setHeaderData(5, QtCore.Qt.Horizontal, "Fix")
    self.model.setHeaderData(6, QtCore.Qt.Horizontal, "Bemerkung")
    self.model.setSort(1, QtCore.Qt.AscendingOrder)
    
    return self.model

方法二:使用自定义ItemDelegate为指定列设置格式

通过给表格的日期、金额列单独设置委托,仅对当前表格生效,灵活性更高。

1. 定义委托类

from PySide6 import QtCore, QtWidgets

class DateDelegate(QtWidgets.QStyledItemDelegate):
    def displayText(self, value, locale):
        # 格式化日期为dd.MM.yyyy格式
        if isinstance(value, QtCore.QDate):
            return value.toString("dd.MM.yyyy")
        elif isinstance(value, str):
            q_date = QtCore.QDate.fromString(value, QtCore.Qt.ISODate)
            return q_date.toString("dd.MM.yyyy")
        return super().displayText(value, locale)

class NumberDelegate(QtWidgets.QStyledItemDelegate):
    def displayText(self, value, locale):
        # 格式化金额为德语区本地化格式
        if isinstance(value, (int, float)):
            de_locale = QtCore.QLocale(QtCore.QLocale.German)
            return de_locale.toString(value, 'f', 2)
        return super().displayText(value, locale)

2. 在表格中设置委托

修改incomeView函数,为对应列绑定委托:

def incomeView(self):
    mod_income = dbc().incomeViewData()
    mod_income.select()
    
    self.ui.load_pages.tbl_income.setModel(mod_income)
    self.ui.load_pages.tbl_income.setColumnHidden(0, True)
    
    # 为日期列(索引1)设置委托
    self.ui.load_pages.tbl_income.setItemDelegateForColumn(1, DateDelegate())
    # 为金额列(索引2)设置委托
    self.ui.load_pages.tbl_income.setItemDelegateForColumn(2, NumberDelegate())
    
    # 表头布局设置保持不变
    for i in range(mod_income.columnCount()):
        self.ui.load_pages.tbl_income.horizontalHeader().setMinimumSectionSize(175)
        self.ui.load_pages.tbl_income.horizontalHeader().setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents)
        self.ui.load_pages.tbl_income.horizontalHeader().setStretchLastSection(True)

注意事项

  • 日期格式化:如果数据库中存储的日期格式不是ISO标准,需要调整QDate.fromString的第二个参数,匹配实际存储格式。
  • 金额格式化:如果数据库中存储的是Decimal类型,可直接在NumberDelegate中适配,Qt会自动转换为数值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:34:59