Reputation: 19329
Model's data()
properly assigns a scaled to 64x64 pixmap to each QModelIndex
. But the monkey gets clipped since the row's height is too short.
The two lines below resize only the second row (why only second?!):
self.tableviewA.resizeColumnToContents(True)
self.tableviewA.resizeRowToContents(True)
Sure I can iterate each row and setRowHeight(row, heightInt)
manually. But that would be an extra calculation for the machine to perform. I wonder if there is a better simpler way to make QTableView
to resize each row to fit the thumb (or any other context) populating it...
Here is the link to monkey icon required to run the example code posted below (right-click to save it as "monkey.png" to the same folder from where a script is run):
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_())
Upvotes: 1
Views: 3694
Reputation: 19329
The problem was in not using
self.tableviewA.resizeRowsToContents()
self.tableviewA.resizeColumnsToContents()
methods which reset the row heights and column widths respectively.
In the solution posted below I have included a elif role == Qt.SizeHintRole:...
too (here for the educational purposes).
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_())
Upvotes: 1