我在 qTableWidget
中设置了按钮第 9 列。它包含 3 个值,因此当单击它时,它会向我的 main 发送包含这些值的信号,从而触发 DoSomething()
方法在我的 main.问题是这条线消耗了很多时间self.tableWidget.setCellWidget(i,9, button)
。这是我的按钮的代码,和 PopulateTable()
问题输出的方法:
class MyPushButton(QtGui.QPushButton):
def __init__(self, value1, value2, value3, main):
super(MyPushButton, self).__init__()
self.__value1 = value1
self.__value2 = value2
self.__value3 = value3
self.__main = main
self.connect(self, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT("triggerOutput()"))
@QtCore.pyqtSlot()
def triggerOutput(self):
self.__main.emit(QtCore.SIGNAL("DoSomethingSignal(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)"), self.__value1 , self.__value2 , self.__value3)
PopulateTable()
我的方法class PYQTEmaszForm(QtGui.QMainWindow)
:
def PopulateTable(self, numberOfRows, rows):
编辑 2 vvvvv
self.tableWidget.setColumnCount(10)
self.tableWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
self.tableWidget.setFocusPolicy(QtCore.Qt.NoFocus)
self.tableWidget.verticalHeader().hide()
self.tableWidget.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
#next line was the problem
#self.tableWidget.verticalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)
self.tableWidget.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
self.tableWidget.resizeColumnsToContents()
^^^^^
self.tableWidget.setVisible(0)
self.tableWidget.setSortingEnabled(0)
self.tableWidget.setRowCount(numberOfRows)
for i in range(0,numberOfRows):
#I set columns 0-8 here like this self.tableWidget.setItem(i, colNum, QtGui.QTableWidgetItem(rows[i][colNum]))
#here is my problem:
button = MyPushButton(value1, value2, value3, self)# note that tose 3 values I can get only here, in a loop, so I must store them in my button that I use as link
button.setText("Click to do something")
startTime = time.time()
self.tableWidget.setCellWidget(i,9, button)
print i," self.tableWidget.setCellWidget(i,9, button) time: ", time.time() - startTime
self.tableWidget.resizeColumnsToContents()
self.tableWidget.setSortingEnabled(1)
self.tableWidget.sortByColumn(0,QtCore.Qt.AscendingOrder)
self.tableWidget.setVisible(1)
时间到cetCellWidget
每行都会增长。这是我得到的 325 行的结果:
0 self.tableWidget.setCellWidget(i,9, button) time: 0.010999917984
1 self.tableWidget.setCellWidget(i,9, button) time: 0.0119998455048
2 self.tableWidget.setCellWidget(i,9, button) time: 0.0130000114441
3 self.tableWidget.setCellWidget(i,9, button) time: 0.0150001049042
# ....
100 self.tableWidget.setCellWidget(i,9, button) time: 0.141999959946
101 self.tableWidget.setCellWidget(i,9, button) time: 0.134000062943
102 self.tableWidget.setCellWidget(i,9, button) time: 0.144999980927
103 self.tableWidget.setCellWidget(i,9, button) time: 0.151000022888
# ....
321 self.tableWidget.setCellWidget(i,9, button) time: 0.209000110626
322 self.tableWidget.setCellWidget(i,9, button) time: 0.211999893188
323 self.tableWidget.setCellWidget(i,9, button) time: 0.213000059128
324 self.tableWidget.setCellWidget(i,9, button) time: 0.212000131607
因此填充表格持续超过 1 分钟。
我的问题是为什么 setCellWidget
需要这么多时间,为什么时间在增长?
我做错了什么?
EDIT1 我尝试过设置简单 QPushButton
像这样:button = QtGui.QPushButton()
,并且setCellWidget
的时间消耗没有差异。方法。所以它不取决于 MyPushButton
小部件。
最佳答案
问题是 setCellWidget
只是一种方便的方法:它没有针对向单个表添加数百个小部件进行优化,因此您所看到的性能下降是不可避免的。
为了获得最佳性能,您必须创建一个自定义委托(delegate)并使用 QStyle
在其 paint
方法中绘制按钮。当然,这也意味着您还必须自己实现所有鼠标处理等。
为了让您了解所涉及的内容,可以找到一些示例代码 here .
编辑:
这是一个基于问题中原始代码的测试脚本。对我来说,这对于 325 行来说只需不到一秒的时间即可完成:
import time
from PyQt4 import QtCore, QtGui
class MyPushButton(QtGui.QPushButton):
def __init__(self, value1, value2, value3, main):
super(MyPushButton, self).__init__()
self.__value1 = value1
self.__value2 = value2
self.__value3 = value3
self.__main = main
self.connect(self, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT("triggerOutput()"))
@QtCore.pyqtSlot()
def triggerOutput(self):
self.__main.emit(QtCore.SIGNAL("DoSomethingSignal(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)"), self.__value1 , self.__value2 , self.__value3)
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.table = QtGui.QTableWidget(self)
self.button = QtGui.QPushButton('Populate', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
layout.addWidget(self.button)
def handleButton(self):
self.populateTable(325)
def populateTable(self, numberOfRows):
self.table.setVisible(0)
self.table.setSortingEnabled(0)
self.table.setRowCount(numberOfRows)
self.table.setColumnCount(10)
for i in range(0, numberOfRows):
for colNum in range(10):
text = 'Text(%d, %d)' % (i, colNum)
self.table.setItem(i, colNum, QtGui.QTableWidgetItem(text))
button = MyPushButton(1, 2, 3, self)
button.setText("Click")
startTime = time.time()
self.table.setCellWidget(i,9, button)
print i," self.tableWidget.setCellWidget(i,9, button) time: ", time.time() - startTime
self.table.resizeColumnsToContents()
self.table.setSortingEnabled(1)
self.table.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.table.setVisible(1)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 300, 1000, 600)
window.show()
sys.exit(app.exec_())
更新:
我不确定到底你想要什么,但是行调整大小问题可能可以通过在填充表格之前将调整大小模式设置为固定
来解决,并且然后将其设置为 ResizeToContents
:
...
self.tableWidget.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
self.tableWidget.verticalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
# populate table
self.table.verticalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)
self.table.resizeColumnsToContents()
self.tableWidget.setSortingEnabled(1)
self.tableWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
关于performance - 将自定义按钮设置为单元格小部件会消耗大量时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22246824/