2017-04-08 100 views
0

我根據組合框的設置(QTableWidget外部)以不同數字格式在QTableWidget中顯示數據。這很好地通過重新定義ItemDelegate的displayText()方法。Qt ItemDelegate帶有QTableWidget的displayText():如何訪問表索引?

我也想根據索引來設置/修改顯示的文本,但是隻有文本和語言環境作爲參數傳遞給displayText()

作爲一種變通方法我也重新定義了paint()方法,因爲這裏的指數傳遞也是如此。這似乎很笨拙我,我也是在窮途末路時,我開始樣式文本 - 純天上掉餡餅編程...

所以,我是不是找錯了樹?是否有更簡單的方法來格式化只有元素(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_()) 

替換重寫的paint例程,並且更簡潔。

回答

1

您可以嘗試覆蓋QStyledItemDelegate::initStyleOption並自己設置text,因爲這是done by qt

+0

感謝名單,我已經加你的建議上述原來的問題。不幸的是我仍然被可能是我真正的問題困擾着:我不明白QStyleOptionViewItem是如何工作的,對我來說它的Qt文檔比其他的更加神祕。你能否給我一個出發點,說明如何實際設計這個項目?我偶然發現了屬性(?)'text'和'font',但我不知道如何設置例如文本對齊,文本和背景顏色。 – Chipmuenk

+0

[文檔](http://doc.qt.io/qt-5.8/qstyleoptionviewitem.html#public-variables)給出所有不同的屬性可以設置,包括'backgroundBrush'和'displayAlignment'的概述。 – m7913d

+0

請注意,您也可以創建自己的答案(並將其標記爲正確),因此問題和答案顯然是分開的,這可能對具有相同問題的其他人有用。 – m7913d