PyQt-QTableView中的复选框列

PyQt-QTableView中的复选框列,第1张

PyQt-QTableView中的复选框列

我为您找到了解决方案。诀窍是:

  1. 编写
    setData
    模型的方法
  2. 总是在
    data
    方法中返回QVariant

这里是。(我必须创建一个名为的类

Dataframe
,以使示例在没有熊猫的情况下工作。请用您的所有
if has_pandas
语句替换所有语句):

from PyQt4 import QtCore, QtGuihas_pandas = Falsetry:  import pandas as pd  has_pandas = Trueexcept:  passclass TableModel(QtCore.QAbstractTableModel):    def __init__(self, parent=None, *args):        super(TableModel, self).__init__()        self.datatable = None        self.headerdata = None    def update(self, dataIn):        print 'Updating Model'        self.datatable = dataIn        print 'Datatable : {0}'.format(self.datatable)        if has_pandas:          headers = dataIn.columns.values        else:          headers = dataIn.columns        header_items = [         str(field)         for field in headers        ]        self.headerdata = header_items        print 'Headers'        print self.headerdata    def rowCount(self, parent=QtCore.QModelIndex()):        return len(self.datatable.index)    def columnCount(self, parent=QtCore.QModelIndex()):        if has_pandas:          return len(self.datatable.columns.values)        else:          return len(self.datatable.columns)    def data(self, index, role=QtCore.Qt.DisplayRole):        if role == QtCore.Qt.DisplayRole: i = index.row() j = index.column() return QtCore.QVariant('{0}'.format(self.datatable.iget_value(i, j)))        else: return QtCore.QVariant()    def setData(self, index, value, role=QtCore.Qt.DisplayRole):        if index.column() == 4: self.datatable.iset_value(index.row(), 4, value) return value        return value    def headerData(self, col, orientation, role):        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: return '{0}'.format(self.headerdata[col])    def flags(self, index):        if index.column() == 4: return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled        else: return QtCore.Qt.ItemIsEnabledclass TableView(QtGui.QTableView):    """    A simple table to demonstrate the QComboBox delegate.    """    def __init__(self, *args, **kwargs):        QtGui.QTableView.__init__(self, *args, **kwargs)        self.setItemDelegateForColumn(4, CheckBoxDelegate(self))class CheckBoxDelegate(QtGui.QStyledItemDelegate):    """    A delegate that places a fully functioning QCheckBox in every    cell of the column to which it's applied    """    def __init__(self, parent):        QtGui.QItemDelegate.__init__(self, parent)    def createEditor(self, parent, option, index):        '''        important, otherwise an editor is created if the user clicks in this cell.        ** Need to hook up a signal to the model        '''        return None    def paint(self, painter, option, index):        '''        Paint a checkbox without the label.        '''        checked = index.data().toBool()        check_box_style_option = QtGui.QStyleOptionButton()        if (index.flags() & QtCore.Qt.ItemIsEditable) > 0: check_box_style_option.state |= QtGui.QStyle.State_Enabled        else: check_box_style_option.state |= QtGui.QStyle.State_Readonly        if checked: check_box_style_option.state |= QtGui.QStyle.State_On        else: check_box_style_option.state |= QtGui.QStyle.State_Off        check_box_style_option.rect = self.getCheckBoxRect(option)        # this will not run - hasFlag does not exist        #if not index.model().hasFlag(index, QtCore.Qt.ItemIsEditable): #check_box_style_option.state |= QtGui.QStyle.State_Readonly        check_box_style_option.state |= QtGui.QStyle.State_Enabled        QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_CheckBox, check_box_style_option, painter)    def editorEvent(self, event, model, option, index):        '''        Change the data in the model and the state of the checkbox        if the user presses the left mousebutton or presses        Key_Space or Key_Select and this cell is editable. Otherwise do nothing.        '''        print 'Check Box editor Event detected : '        print event.type()        if not (index.flags() & QtCore.Qt.ItemIsEditable) > 0: return False        print 'Check Box editor Event detected : passed first check'        # Do not change the checkbox-state        if event.type() == QtCore.QEvent.MouseButtonPress:          return False        if event.type() == QtCore.QEvent.MouseButtonRelease or event.type() == QtCore.QEvent.MouseButtonDblClick: if event.button() != QtCore.Qt.LeftButton or not self.getCheckBoxRect(option).contains(event.pos()):     return False if event.type() == QtCore.QEvent.MouseButtonDblClick:     return True        elif event.type() == QtCore.QEvent.KeyPress: if event.key() != QtCore.Qt.Key_Space and event.key() != QtCore.Qt.Key_Select:     return False        else: return False        # Change the checkbox-state        self.setModelData(None, model, index)        return True    def setModelData (self, editor, model, index):        '''        The user wanted to change the old state in the opposite.        '''        print 'SetModelData'        newValue = not index.data().toBool()        print 'New Value : {0}'.format(newValue)        model.setData(index, newValue, QtCore.Qt.EditRole)    def getCheckBoxRect(self, option):        check_box_style_option = QtGui.QStyleOptionButton()        check_box_rect = QtGui.QApplication.style().subElementRect(QtGui.QStyle.SE_CheckBoxIndicator, check_box_style_option, None)        check_box_point = QtCore.QPoint (option.rect.x() +      option.rect.width() / 2 -      check_box_rect.width() / 2,      option.rect.y() +      option.rect.height() / 2 -      check_box_rect.height() / 2)        return QtCore.QRect(check_box_point, check_box_rect.size())###############################################################################################################################class Dataframe(dict):  def __init__(self, columns, values):    if len(values) != len(columns):      raise Exception("Bad values")    self.columns = columns    self.values = values    self.index = values[0]    super(Dataframe, self).__init__(dict(zip(columns, values)))    pass  def iget_value(self, i, j):    return(self.values[j][i])  def iset_value(self, i, j, value):    self.values[j][i] = valueif __name__=="__main__":    from sys import argv, exit    class Widget(QtGui.QWidget):        """        A simple test widget to contain and own the model and table.        """        def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) l=QtGui.QVBoxLayout(self) cdf = self.get_data_frame() self._tm=TableModel(self) self._tm.update(cdf) self._tv=TableView(self) self._tv.setModel(self._tm) for row in range(0, self._tm.rowCount()):     self._tv.openPersistentEditor(self._tm.index(row, 4)) self.setGeometry(300, 300, 550, 200) l.addWidget(self._tv)        def get_data_frame(self): if has_pandas:   df = pd.Dataframe({'Name':['a','b','c','d'],   'First':[2.3,5.4,3.1,7.7], 'Last':[23.4,11.2,65.3,88.8], 'Class':[1,1,2,1], 'Valid':[True, False, True, False]}) else:   columns = ['Name', 'First', 'Last', 'Class', 'Valid']   values = [['a','b','c','d'], [2.3,5.4,3.1,7.7], [23.4,11.2,65.3,88.8], [1,1,2,1], [True, False, True, False]]   df = Dataframe(columns, values) return df    a=QtGui.QApplication(argv)    w=Widget()    w.show()    w.raise_()    exit(a.exec_())


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5642781.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存