我在QTableWidget中以各种数字格式显示数据,具体取决于组合框的设置(在QTableWidget外部)。通过重新定义ItemDelegate的displayText()
方法,这很有效。
我还想根据其索引来设置/修改显示的文本,但是,只有文本和语言环境作为参数传递给displayText()
。
作为一种解决方法,我还重新定义了paint()
方法,因为这里也传递了索引。这对我来说似乎非常笨拙,当我开始设计文本时,我也在绳索的尽头 - 纯粹的Cargo Cult编程...
所以,我是在咆哮错误的树吗?是否有更简单的格式化方式,例如只有元素(0,1)(见下面的代码),可能在displayText()
?
以下代码只是一个最小的工作示例,
下的完整代码https://github.com/chipmuenk/pyFDA/blob/coeff_table/pyfda/input_widgets/filter_coeffs.py
# -*- coding: utf-8 -*-
from __future__ import print_function, division, unicode_literals, absolute_import
#from PyQt4.QtGui import ...
from PyQt5.QtWidgets import (QWidget, QApplication, QTableWidget,
QTableWidgetItem, QVBoxLayout, QStyledItemDelegate)
from PyQt5.QtWidgets import QStyle
from PyQt5.QtGui import QFont
#from PyQt4.QtGui import QStyle, QFont
import numpy as np
class ItemDelegate(QStyledItemDelegate):
"""
The following methods are subclassed to replace display and editor of the
QTableWidget.
"""
def __init__(self, parent):
"""
Pass instance `parent` of parent class (TestTable)
"""
super(ItemDelegate, self).__init__(parent)
self.parent = parent # instance of the parent (not the base) class
def paint(self, painter, option, index):
"""
painter: instance of QPainter
option: instance of QStyleOptionViewItem(V4?)
index: instance of QModelIndex
"""
style_option = option
# read text to be shown:
if index.row() == 0 and index.column() == 1: # always display "1!" at index (0,1)
style_option.text = "1!"
style_option.font.setBold(True)
# now paint the cell
self.parent.style().drawControl(QStyle.CE_ItemViewItem, style_option, painter)
else:
super(ItemDelegate, self).paint(painter, option, index) # default painter
def displayText(self, text, locale):
"""
Display `text` in the selected with the selected number
of digits
text: string / QVariant from QTableWidget to be rendered
locale: locale for the text
"""
data = text # .toString() # Python 2: need to convert to "normal" string
return "{0:>{1}}".format(data, 4)
class TestTable(QWidget):
""" Create widget for viewing / editing / entering data """
def __init__(self, parent):
super(TestTable, self).__init__(parent)
self.bfont = QFont()
self.bfont.setBold(True)
self.tblCoeff = QTableWidget(self)
self.tblCoeff.setItemDelegate(ItemDelegate(self))
layVMain = QVBoxLayout()
layVMain.addWidget(self.tblCoeff)
self.setLayout(layVMain)
self.ba = np.random.randn(3,4) # test data
self._refresh_table()
def _refresh_table(self):
""" (Re-)Create the displayed table from self.ba """
num_cols = 3
num_rows = 4
self.tblCoeff.setRowCount(num_rows)
self.tblCoeff.setColumnCount(num_cols)
for col in range(num_cols):
for row in range(num_rows):
# set table item from self.ba
item = self.tblCoeff.item(row, col)
if item: # does item exist?
item.setText(str(self.ba[col][row]))
else: # no, construct it:
self.tblCoeff.setItem(row,col,QTableWidgetItem(
str(self.ba[col][row])))
self.tblCoeff.resizeColumnsToContents()
self.tblCoeff.resizeRowsToContents()
#------------------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
mainw = TestTable(None)
app.setActiveWindow(mainw)
mainw.show()
sys.exit(app.exec_())
编辑:============================================= ====================
@ m7913d的建议对我有用,我重写了initStyleOption()方法而不是paint()方法,这看起来更简洁。这是更新的代码(所以我已经部分回答了我自己的问题):
# -*- coding: utf-8 -*-
from __future__ import print_function, division, unicode_literals, absolute_import
#from PyQt4.QtGui import ...
from PyQt5.QtWidgets import (QWidget, QApplication, QTableWidget,
QTableWidgetItem, QVBoxLayout, QStyledItemDelegate)
from PyQt5.QtWidgets import QStyle
from PyQt5.QtGui import QFont
#from PyQt4.QtGui import QStyle, QFont
import numpy as np
class ItemDelegate(QStyledItemDelegate):
"""
The following methods are subclassed to replace display and editor of the
QTableWidget.
"""
def __init__(self, parent):
"""
Pass instance `parent` of parent class (TestTable)
"""
super(ItemDelegate, self).__init__(parent)
self.parent = parent # instance of the parent (not the base) class
def initStyleOption(self, option, index):
"""
Initialize `option` with the values using the `index` index. When the
item (0,1) is processed, it is styled especially. All other items are
passed to the original `initStyleOption()` which then calls `displayText()`.
"""
if index.row() == 0 and index.column() == 1: # a[0]: always 1
option.text = "1!" # QString object
option.font.setBold(True)
option.displayAlignment = Qt.AlignRight
#option.backgroundBrush ...
else:
# continue with the original `initStyleOption()`
super(ItemDelegate, self).initStyleOption(option, index)
def displayText(self, text, locale):
"""
Display `text` in the selected with the selected number
of digits
text: string / QVariant from QTableWidget to be rendered
locale: locale for the text
"""
data = text # .toString() # Python 2: need to convert to "normal" string
return "{0:>{1}}".format(data, 4)
class TestTable(QWidget):
""" Create widget for viewing / editing / entering data """
def __init__(self, parent):
super(TestTable, self).__init__(parent)
self.bfont = QFont()
self.bfont.setBold(True)
self.tblCoeff = QTableWidget(self)
self.tblCoeff.setItemDelegate(ItemDelegate(self))
layVMain = QVBoxLayout()
layVMain.addWidget(self.tblCoeff)
self.setLayout(layVMain)
self.ba = np.random.randn(3,4) # test data
self._refresh_table()
def _refresh_table(self):
""" (Re-)Create the displayed table from self.ba """
num_cols = 3
num_rows = 4
self.tblCoeff.setRowCount(num_rows)
self.tblCoeff.setColumnCount(num_cols)
for col in range(num_cols):
for row in range(num_rows):
# set table item from self.ba
item = self.tblCoeff.item(row, col)
if item: # does item exist?
item.setText(str(self.ba[col][row]))
else: # no, construct it:
self.tblCoeff.setItem(row,col,QTableWidgetItem(
str(self.ba[col][row])))
self.tblCoeff.resizeColumnsToContents()
self.tblCoeff.resizeRowsToContents()
#------------------------------------------------------------------------------
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
mainw = TestTable(None)
app.setActiveWindow(mainw)
mainw.show()
sys.exit(app.exec_())
替换被覆盖的绘制例程,并且更简洁。