1

我根据组合框的设置(在 QTableWidget 之外)以各种数字格式在 QTableWidget 中显示数据。displayText()这可以通过重新定义ItemDelegate的方法来很好地工作。

我还想根据其索引对显示的文本进行样式/修改,但是,只有文本和语言环境作为参数传递给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_())

替换了覆盖的绘制程序并且更简洁。

4

1 回答 1

2

您可以尝试覆盖QStyledItemDelegate::initStyleOption并设置text自己,因为这现在由 qt 完成

option->text = displayText(value, option->locale);
于 2017-04-08T20:41:03.597 回答