Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在QTableView单元格中显示具有原始大小比率的图像?_Python_Pyqt - Fatal编程技术网

Python 如何在QTableView单元格中显示具有原始大小比率的图像?

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

我确实创建了一个qtableview,其中第1列有图像,并成功地制作了ImageDelegate,它可以处理单元格中的图像显示,但问题是以原始比率显示它们,它们似乎被拉伸了,可能会小一些

图像示例:

使用的示例数据库: 守则:

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现在添加了它。非常感谢您为我解决了它,除此之外,您还编辑了我的代码,使它更具可读性和更好。非常感谢♥