如何改变QTableView图片大小
How to change QTableView image size
模型的 data()
正确地为每个 QModelIndex
分配了一个缩放为 64x64 的像素图。但是由于行的高度太短,猴子被剪掉了。
下面两行仅调整第二行的大小(为什么只调整第二行?!):
self.tableviewA.resizeColumnToContents(True)
self.tableviewA.resizeRowToContents(True)
当然,我可以手动迭代每一行和 setRowHeight(row, heightInt)
。但这将是机器执行的额外计算。我想知道是否有更好更简单的方法让 QTableView
调整每一行的大小以适应填充它的拇指(或任何其他上下文)...
这是 运行 下面发布的示例代码所需的 link 猴子图标(right-click 将其另存为 "monkey.png" 到与脚本是 运行):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.images = ['monkey.png','monkey.png','monkey.png']
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
self.thumbSize=64
def resizePixmap(self, mult):
self.thumbSize=self.thumbSize*mult
self.reset()
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 3
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[row])
elif role == Qt.DecorationRole:
image=self.images[row]
pixmap=QPixmap(image).scaled(QSize(self.thumbSize, self.thumbSize), Qt.KeepAspectRatio)
return pixmap
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
self.tablemodel=Model(self)
self.tableviewA=QTableView()
self.tableviewA.setModel(self.tablemodel)
buttonPlus=QPushButton('Plus')
buttonMinus=QPushButton('Minus')
buttonPlus.clicked.connect(self.plus)
buttonMinus.clicked.connect(self.minus)
layout = QVBoxLayout(self)
layout.addWidget(self.tableviewA)
layout.addWidget(buttonPlus)
layout.addWidget(buttonMinus)
self.setLayout(layout)
self.tableviewA.resizeColumnToContents(True)
self.tableviewA.resizeRowToContents(True)
def plus(self, arg):
self.tablemodel.resizePixmap(1.1)
thumbSize=self.tableviewA.model().thumbSize
totalRows=self.tablemodel.rowCount(QModelIndex())
for row in range(totalRows):
self.tableviewA.setRowHeight(row, thumbSize*1.1)
def minus(self, arg):
self.tablemodel.resizePixmap(0.9)
thumbSize=self.tableviewA.model().thumbSize
totalRows=self.tablemodel.rowCount(QModelIndex())
for row in range(totalRows):
self.tableviewA.setRowHeight(row, thumbSize*0.9)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
问题在于没有使用
self.tableviewA.resizeRowsToContents()
self.tableviewA.resizeColumnsToContents()
分别重置行高和列宽的方法。
在下面发布的解决方案中,我也包含了一个 elif role == Qt.SizeHintRole:...
(此处用于教育目的)。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.images = ['monkey.png','monkey.png','monkey.png']
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
self.thumbSize=64
def resizePixmap(self, mult):
self.thumbSize=self.thumbSize*mult
self.reset()
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 3
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[row])
elif role == Qt.DecorationRole:
image=self.images[row]
pixmap=QPixmap(image).scaled(QSize(self.thumbSize, self.thumbSize), Qt.KeepAspectRatio)
return pixmap
elif role == Qt.SizeHintRole:
print 'Model.data(role == Qt.SizeHintRole) row: %s; column %s'%(index.row(), index.column())
# return QSize(32, 32)
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
self.tablemodel=Model(self)
self.tableviewA=QTableView()
self.tableviewA.setModel(self.tablemodel)
buttonResize=QPushButton('Resize')
buttonZoomIn=QPushButton('Zoom In')
buttonZoomOut=QPushButton('Zoom Out')
buttonResize.clicked.connect(self.resizeView)
buttonZoomIn.clicked.connect(self.zoomIn)
buttonZoomOut.clicked.connect(self.zoomOut)
layout = QVBoxLayout(self)
layout.addWidget(self.tableviewA)
layout.addWidget(buttonResize)
layout.addWidget(buttonZoomIn)
layout.addWidget(buttonZoomOut)
self.setLayout(layout)
# self.tableviewA.resizeRowsToContents()
# self.tableviewA.resizeColumnsToContents()
def zoomIn(self, arg):
self.tablemodel.resizePixmap(1.1)
self.resizeView()
def zoomOut(self, arg):
self.tablemodel.resizePixmap(0.9)
self.resizeView()
def resizeView(self):
self.tableviewA.resizeRowsToContents()
self.tableviewA.resizeColumnsToContents()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
模型的 data()
正确地为每个 QModelIndex
分配了一个缩放为 64x64 的像素图。但是由于行的高度太短,猴子被剪掉了。
下面两行仅调整第二行的大小(为什么只调整第二行?!):
self.tableviewA.resizeColumnToContents(True)
self.tableviewA.resizeRowToContents(True)
当然,我可以手动迭代每一行和 setRowHeight(row, heightInt)
。但这将是机器执行的额外计算。我想知道是否有更好更简单的方法让 QTableView
调整每一行的大小以适应填充它的拇指(或任何其他上下文)...
这是 运行 下面发布的示例代码所需的 link 猴子图标(right-click 将其另存为 "monkey.png" 到与脚本是 运行):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.images = ['monkey.png','monkey.png','monkey.png']
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
self.thumbSize=64
def resizePixmap(self, mult):
self.thumbSize=self.thumbSize*mult
self.reset()
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 3
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[row])
elif role == Qt.DecorationRole:
image=self.images[row]
pixmap=QPixmap(image).scaled(QSize(self.thumbSize, self.thumbSize), Qt.KeepAspectRatio)
return pixmap
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
self.tablemodel=Model(self)
self.tableviewA=QTableView()
self.tableviewA.setModel(self.tablemodel)
buttonPlus=QPushButton('Plus')
buttonMinus=QPushButton('Minus')
buttonPlus.clicked.connect(self.plus)
buttonMinus.clicked.connect(self.minus)
layout = QVBoxLayout(self)
layout.addWidget(self.tableviewA)
layout.addWidget(buttonPlus)
layout.addWidget(buttonMinus)
self.setLayout(layout)
self.tableviewA.resizeColumnToContents(True)
self.tableviewA.resizeRowToContents(True)
def plus(self, arg):
self.tablemodel.resizePixmap(1.1)
thumbSize=self.tableviewA.model().thumbSize
totalRows=self.tablemodel.rowCount(QModelIndex())
for row in range(totalRows):
self.tableviewA.setRowHeight(row, thumbSize*1.1)
def minus(self, arg):
self.tablemodel.resizePixmap(0.9)
thumbSize=self.tableviewA.model().thumbSize
totalRows=self.tablemodel.rowCount(QModelIndex())
for row in range(totalRows):
self.tableviewA.setRowHeight(row, thumbSize*0.9)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
问题在于没有使用
self.tableviewA.resizeRowsToContents()
self.tableviewA.resizeColumnsToContents()
分别重置行高和列宽的方法。
在下面发布的解决方案中,我也包含了一个 elif role == Qt.SizeHintRole:...
(此处用于教育目的)。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.images = ['monkey.png','monkey.png','monkey.png']
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
self.thumbSize=64
def resizePixmap(self, mult):
self.thumbSize=self.thumbSize*mult
self.reset()
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 3
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[row])
elif role == Qt.DecorationRole:
image=self.images[row]
pixmap=QPixmap(image).scaled(QSize(self.thumbSize, self.thumbSize), Qt.KeepAspectRatio)
return pixmap
elif role == Qt.SizeHintRole:
print 'Model.data(role == Qt.SizeHintRole) row: %s; column %s'%(index.row(), index.column())
# return QSize(32, 32)
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
self.tablemodel=Model(self)
self.tableviewA=QTableView()
self.tableviewA.setModel(self.tablemodel)
buttonResize=QPushButton('Resize')
buttonZoomIn=QPushButton('Zoom In')
buttonZoomOut=QPushButton('Zoom Out')
buttonResize.clicked.connect(self.resizeView)
buttonZoomIn.clicked.connect(self.zoomIn)
buttonZoomOut.clicked.connect(self.zoomOut)
layout = QVBoxLayout(self)
layout.addWidget(self.tableviewA)
layout.addWidget(buttonResize)
layout.addWidget(buttonZoomIn)
layout.addWidget(buttonZoomOut)
self.setLayout(layout)
# self.tableviewA.resizeRowsToContents()
# self.tableviewA.resizeColumnsToContents()
def zoomIn(self, arg):
self.tablemodel.resizePixmap(1.1)
self.resizeView()
def zoomOut(self, arg):
self.tablemodel.resizePixmap(0.9)
self.resizeView()
def resizeView(self):
self.tableviewA.resizeRowsToContents()
self.tableviewA.resizeColumnsToContents()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())