Python 如何在QTableView单元格中显示具有原始大小比率的图像?
我确实创建了一个qtableview,其中第1列有图像,并成功地制作了ImageDelegate,它可以处理单元格中的图像显示,但问题是以原始比率显示它们,它们似乎被拉伸了,可能会小一些 图像示例: 使用的示例数据库: 守则:Python 如何在QTableView单元格中显示具有原始大小比率的图像?,python,pyqt,Python,Pyqt,我确实创建了一个qtableview,其中第1列有图像,并成功地制作了ImageDelegate,它可以处理单元格中的图像显示,但问题是以原始比率显示它们,它们似乎被拉伸了,可能会小一些 图像示例: 使用的示例数据库: 守则: from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import (QApplica
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog,
QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit,
QVBoxLayout, QCheckBox, QTableWidgetItem, QAbstractItemView, QTableWidget, QTableView, QStyledItemDelegate)
import sqlite3
class Main(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.table = QtWidgets.QTableView()
conn = sqlite3.connect("math.db")
conn.text_factory = bytes
self.cur = conn.cursor()
data = self.cur.execute("select * from problems;").fetchall();conn.close()
self.dims = (lambda x: (len(x), len(x[0])))(data) #(rows number, col number)
self.model = TableModel([[j.decode("utf-8", "ignore") if u!=1 else j for u, j in enumerate(i)] for i in data])
self.table.setModel(self.model)
self.table.setItemDelegateForColumn(1, ImageDelegate(self))
#self.table.resizeColumnsToContents()
#self.table.resizeRowsToContents()
self.setCentralWidget(self.table)
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, data):
super(TableModel, self).__init__()
self._data = data
def data(self, index, role):
if role == Qt.DisplayRole:
return self._data[index.row()][index.column()]
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._data[0])
class ImageDelegate(QStyledItemDelegate):
def __init__(self, parent):
QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index):
## [ Here is the part that needs something added or fixed ]
pixmap = QtGui.QPixmap()
pixmap.loadFromData(index.data(), "jpg")
painter.drawPixmap(option.rect, pixmap)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.resize(600,600)
main.show()
app.exec_()
这是一段代码片段,我以前用在QtableWidget上,它为我解决了这个问题,但现在用QtableView,情况似乎有所不同。
snippt类:
class ScaledPixmapLabel(QtWidgets.QLabel):
def __init__(self):
super().__init__()
self.setScaledContents(True)
def paintEvent(self, event):
if self.pixmap():
pm = self.pixmap()
originalRatio = pm.width() / pm.height()
currentRatio = self.width() / self.height()
if originalRatio != currentRatio:
qp = QtGui.QPainter(self)
pm = self.pixmap().scaled(self.size(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
rect = QtCore.QRect(0, 0, pm.width(), pm.height())
rect.moveCenter(self.rect().center())
qp.drawPixmap(rect, pm)
return
super().paintEvent(event)
必须使列“1”及其所有行的大小取决于内容,即图像。另一方面,我没有制作个性化的绘画,而是把它作为一个图标。还应确保图标位于中心位置:
from PyQt5 import QtWidgets, QtGui, QtCore
import sqlite3
class ImageDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super(ImageDelegate, self).initStyleOption(option, index)
pixmap = QtGui.QPixmap()
pixmap.loadFromData(index.data(), "jpg")
if not pixmap.isNull():
option.features |= QtWidgets.QStyleOptionViewItem.HasDecoration
option.icon = QtGui.QIcon(pixmap)
option.decorationSize = pixmap.size() / pixmap.devicePixelRatio()
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, data):
super(TableModel, self).__init__()
self._data = data
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return self._data[index.row()][index.column()]
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._data[0])
class ImageCenterProxyStyle(QtWidgets.QProxyStyle):
def subElementRect(self, subElement, option, widget=None):
r = super(ImageCenterProxyStyle, self).subElementRect(
subElement, option, widget
)
if subElement == QtWidgets.QStyle.SE_ItemViewItemDecoration:
r.moveCenter(option.rect.center())
return r
class Main(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.table = QtWidgets.QTableView()
conn = sqlite3.connect("math.db")
conn.text_factory = bytes
self.cur = conn.cursor()
data = self.cur.execute("select * from problems;").fetchall()
conn.close()
self.dims = (lambda x: (len(x), len(x[0])))(data) # (rows number, col number)
self.model = TableModel(
[
[j.decode("utf-8", "ignore") if u != 1 else j for u, j in enumerate(i)]
for i in data
]
)
self.table.setModel(self.model)
self.table.setItemDelegateForColumn(1, ImageDelegate(self))
self.table.resizeRowsToContents()
self.table.horizontalHeader().setSectionResizeMode(
1, QtWidgets.QHeaderView.ResizeToContents
)
proxy = ImageCenterProxyStyle(self.table.style())
self.table.setStyle(proxy)
self.setCentralWidget(self.table)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.resize(600, 600)
main.show()
app.exec_()
@eyllanesc现在添加了它。非常感谢您为我解决了它,除此之外,您还编辑了我的代码,使它更具可读性和更好。非常感谢♥