我想创建一个Qt表小部件,每秒增加大约20个新行(最大值为10000)。旧行永远不会改变。
首先我使用了QTableWidget,但是我看到CPU%随着表格大小的增加而增加,并且在总共大约1000行时达到100%。
所以我尝试创建自己的模型,每5秒才会生成beginInsertRows
和endInsertRows
。我希望CPU%会变得不变,因为我只发出 new 行,但我发现它仍然会上升到100%。
所以我检查了我在发出之间获得的data()
次呼叫的数量,我看到它等于 240 * total_num_rows 。
''' How to display each item '''
class BindedItemView(object):
def __init__(self, item):
self._data = item
#--------------------------------------------------------------------#
def _text(self, index):
return QVariant()
#--------------------------------------------------------------------#
def _font(self, index):
return QVariant()
#--------------------------------------------------------------------#
def _background(self, index):
return QVariant()
#--------------------------------------------------------------------#
def _foreground(self, index):
return QVariant()
#--------------------------------------------------------------------#
def get(self, role, col):
if role == Qt.DisplayRole:
return self._text(col)
if role == Qt.FontRole:
return self._font(col)
if role == Qt.ForegroundRole:
return self._foreground(col)
if role == Qt.BackgroundRole:
return self._background(col)
return QVariant()
class BindedTableModel(QAbstractTableModel):
end_of_process_signal = pyqtSignal()
#--------------------------------------------------------------------#
def __init__(self, headers, item_view):
super(BindedTableModel, self).__init__()
self._headers = headers
self._item_view = item_view
self._items = []
self._last_row_count = 0
self._num_data_requests = 0
#--------------------------------------------------------------------#
def _index(self, item):
return self._items.index(item)
#--------------------------------------------------------------------#
def _indexSorted(self, item):
return bisect.bisect(self._items, item)
#--------------------------------------------------------------------#
def _refreshView(self):
row_count = len(self._items)
print "DATA REQUESTS: %u" % self._num_data_requests
self._num_data_requests = 0
if self._last_row_count < row_count:
print "INSERT ROWS: %u %u" % (self._last_row_count, row_count - 1)
self.beginInsertRows(QModelIndex(), self._last_row_count, row_count - 1)
self.endInsertRows()
# elif self._last_row_count > row_count:
# self.beginRemoveRows(QModelIndex(), row_count, self._last_row_count - 1)
# self.endRemoveRows()
# else:
# top_left = self.createIndex(0, 0)
# bottom_right = self.createIndex(row_count - 1, self.columnCount() - 1)
# self.dataChanged.emit(top_left, bottom_right)
self._last_row_count = row_count
#--------------------------------------------------------------------#
def _onUpdate(self):
pass
#--------------------------------------------------------------------#
def _addItem(self, item, pos):
self._items.insert(pos, item)
self._onUpdate()
#--------------------------------------------------------------------#
def _removeItem(self, pos):
self._items.pop(pos)
self._onUpdate()
#--------------------------------------------------------------------#
def appendItem(self, item):
self._addItem(item, len(self._items))
#--------------------------------------------------------------------#
def addItemSorted(self, item):
self._addItem(item, self._indexSorted(item))
#--------------------------------------------------------------------#
def removeItem(self, item):
self._removeItem(self._index(item))
#--------------------------------------------------------------------#
def clear(self):
self._items = []
#--------------------------------------------------------------------#
def refreshView(self):
self._refreshView()
#--------------------------------------------------------------------#
'''
Override
'''
def rowCount(self, parent = None):
return len(self._items)
#--------------------------------------------------------------------#
'''
Override
'''
def columnCount(self, parent = None):
return len(self._headers)
#--------------------------------------------------------------------#
'''
Override
'''
def data(self, index, role):
self._num_data_requests += 1
item = self._items[index.row()]
view = self._item_view(item)
return view.get(role, index.column())
#--------------------------------------------------------------------#
'''
Override
'''
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return self._headers[section]
return QVariant()
#--------------------------------------------------------------------#
'''
Override
'''
def setData(self, index, value, role):
if role == Qt.DisplayRole:
pass
#--------------------------------------------------------------------#
def __iter__(self):
return self._items.__iter__()
#--------------------------------------------------------------------#
def __contains__(self, item):
return item in self._items
答案 0 :(得分:1)
这是一种解决方法,但将模型限制为row count < 1000
会产生恒定的CPU%。
因此,对我来说,一个优雅的解决方案是创建一个“分页”表视图,一次只显示N行(并且用户可以控制当前显示的窗口)。
这会产生出色的CPU以及更好的可用性,因此我认为最初的问题并不相关。