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
相关产品推荐
相关产品推荐

