PyQt5 tableView 显示底片是红色的 (x.xx)
PyQt5 tableView show negatives are red and (x.xx)
首先感谢你试图帮助我。我在网上找到了一些非常接近我需要它做的代码,但我一直无法做到最后一点。我希望 csv(tableView)中的任何负数显示为红色并格式化为(x.xx),正数为 x.xx。我在网上找到了一些关于更改单元格背景的代码,但我想更改字体和使用抽象模型的示例,我需要用抽象而不是标准来完成所有这些吗?如果我需要抽象地做,你能提供例子吗(我对这一切都很陌生)。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import csv
import locale
from PyQt5 import QtCore, QtGui, QtWidgets
class MyWindow(QtWidgets.QWidget):
def __init__(self, fileName, parent=None):
super(MyWindow, self).__init__(parent)
locale.setlocale(locale.LC_ALL, '')
self.fileName = fileName
self.model = QtGui.QStandardItemModel(self)
self.tableView = QtWidgets.QTableView(self)
self.tableView.setModel(self.model)
self.tableView.horizontalHeader().setStretchLastSection(True)
self.pushButtonLoad = QtWidgets.QPushButton(self)
self.pushButtonLoad.setText("Load Csv File!")
self.pushButtonLoad.clicked.connect(self.on_pushButtonLoad_clicked)
self.pushButtonWrite = QtWidgets.QPushButton(self)
self.pushButtonWrite.setText("Write Csv File!")
self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked)
self.layoutVertical = QtWidgets.QVBoxLayout(self)
self.layoutVertical.addWidget(self.tableView)
self.layoutVertical.addWidget(self.pushButtonLoad)
self.layoutVertical.addWidget(self.pushButtonWrite)
def loadCsv(self, fileName):
with open(fileName, "r") as fileInput:
# skip header
next(fileInput)
for row in csv.reader(fileInput):
# convert to $x.xx and ($x.xx)
row[-1] = float(row[-1])
row[-1] = locale.currency(row[-1], grouping=True)
items = [
QtGui.QStandardItem(field)
for field in row
]
self.model.appendRow(items)
def writeCsv(self, fileName):
with open(fileName, "w", newline='') as fileOutput:
writer = csv.writer(fileOutput)
for rowNumber in range(self.model.rowCount()):
fields = [
self.model.data(
self.model.index(rowNumber, columnNumber),
QtCore.Qt.DisplayRole
)
for columnNumber in range(self.model.columnCount())
]
writer.writerow(fields)
@QtCore.pyqtSlot()
def on_pushButtonWrite_clicked(self):
self.writeCsv(self.fileName)
@QtCore.pyqtSlot()
def on_pushButtonLoad_clicked(self):
self.loadCsv(self.fileName)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow("data.csv")
main.show()
sys.exit(app.exec_())
要更改信息的显示格式,有几个选项:
覆盖模型的数据方法,使其 returns 与标准角色关联的必要值,例如在本例中 Qt::DisplayRole 和 Qt::ForegroundRole ,
使用代理,例如 QIdentityProxyModel 或者 QSortFilterProxyModel,方法是像以前的方法一样覆盖数据方法,或者
创建委托自定义绘画
在这种情况下,我将使用最后一种方法,因为它更灵活,因为如果您想在多个视图中显示模型的信息以形成不同的形式,并且您还可以修改不是由模型确定的其他属性,但是由风格等其他元素决定。
综合以上,解决方案是:
class CustomDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super(CustomDelegate, self).initStyleOption(option, index)
try:
value = float(option.text)
except ValueError:
return
option.text = "{0:.2f}".format(value)
brush = (
option.palette.brush(QtGui.QPalette.Text)
if value >= 0
else QtGui.QBrush(QtGui.QColor("red"))
)
option.palette.setBrush(QtGui.QPalette.Text, brush)
self.tableView = QtWidgets.QTableView(self)
# ...
delegate = CustomDelegate(self.tableView)
self.tableView.setItemDelegateForColumn(1, delegate)
首先感谢你试图帮助我。我在网上找到了一些非常接近我需要它做的代码,但我一直无法做到最后一点。我希望 csv(tableView)中的任何负数显示为红色并格式化为(x.xx),正数为 x.xx。我在网上找到了一些关于更改单元格背景的代码,但我想更改字体和使用抽象模型的示例,我需要用抽象而不是标准来完成所有这些吗?如果我需要抽象地做,你能提供例子吗(我对这一切都很陌生)。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import csv
import locale
from PyQt5 import QtCore, QtGui, QtWidgets
class MyWindow(QtWidgets.QWidget):
def __init__(self, fileName, parent=None):
super(MyWindow, self).__init__(parent)
locale.setlocale(locale.LC_ALL, '')
self.fileName = fileName
self.model = QtGui.QStandardItemModel(self)
self.tableView = QtWidgets.QTableView(self)
self.tableView.setModel(self.model)
self.tableView.horizontalHeader().setStretchLastSection(True)
self.pushButtonLoad = QtWidgets.QPushButton(self)
self.pushButtonLoad.setText("Load Csv File!")
self.pushButtonLoad.clicked.connect(self.on_pushButtonLoad_clicked)
self.pushButtonWrite = QtWidgets.QPushButton(self)
self.pushButtonWrite.setText("Write Csv File!")
self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked)
self.layoutVertical = QtWidgets.QVBoxLayout(self)
self.layoutVertical.addWidget(self.tableView)
self.layoutVertical.addWidget(self.pushButtonLoad)
self.layoutVertical.addWidget(self.pushButtonWrite)
def loadCsv(self, fileName):
with open(fileName, "r") as fileInput:
# skip header
next(fileInput)
for row in csv.reader(fileInput):
# convert to $x.xx and ($x.xx)
row[-1] = float(row[-1])
row[-1] = locale.currency(row[-1], grouping=True)
items = [
QtGui.QStandardItem(field)
for field in row
]
self.model.appendRow(items)
def writeCsv(self, fileName):
with open(fileName, "w", newline='') as fileOutput:
writer = csv.writer(fileOutput)
for rowNumber in range(self.model.rowCount()):
fields = [
self.model.data(
self.model.index(rowNumber, columnNumber),
QtCore.Qt.DisplayRole
)
for columnNumber in range(self.model.columnCount())
]
writer.writerow(fields)
@QtCore.pyqtSlot()
def on_pushButtonWrite_clicked(self):
self.writeCsv(self.fileName)
@QtCore.pyqtSlot()
def on_pushButtonLoad_clicked(self):
self.loadCsv(self.fileName)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow("data.csv")
main.show()
sys.exit(app.exec_())
要更改信息的显示格式,有几个选项:
覆盖模型的数据方法,使其 returns 与标准角色关联的必要值,例如在本例中 Qt::DisplayRole 和 Qt::ForegroundRole ,
使用代理,例如 QIdentityProxyModel 或者 QSortFilterProxyModel,方法是像以前的方法一样覆盖数据方法,或者
创建委托自定义绘画
在这种情况下,我将使用最后一种方法,因为它更灵活,因为如果您想在多个视图中显示模型的信息以形成不同的形式,并且您还可以修改不是由模型确定的其他属性,但是由风格等其他元素决定。
综合以上,解决方案是:
class CustomDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super(CustomDelegate, self).initStyleOption(option, index)
try:
value = float(option.text)
except ValueError:
return
option.text = "{0:.2f}".format(value)
brush = (
option.palette.brush(QtGui.QPalette.Text)
if value >= 0
else QtGui.QBrush(QtGui.QColor("red"))
)
option.palette.setBrush(QtGui.QPalette.Text, brush)
self.tableView = QtWidgets.QTableView(self)
# ...
delegate = CustomDelegate(self.tableView)
self.tableView.setItemDelegateForColumn(1, delegate)