正确的表格缩放

问题描述 投票:0回答:1

我的代码为 QGraphicsView 创建一个场景,其中包含一个 QGraphicsProxyWidget,其中包含一个 QTableWidget。我尝试根据列和行的大小来缩放表格和 QGraphicsProxyWidget,但我无法实现表格始终与其内容的大小相对应并且没有滚动,这会隐藏根本不适合的行或列。

from PySide6.QtCore import Qt
from PySide6.QtGui import QIcon, QPixmap, QBrush
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QGraphicsTextItem, \
    QTableWidget, QTableWidgetItem, QGraphicsProxyWidget, QStyledItemDelegate
import sys


class ImageDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        super(ImageDelegate, self).__init__(parent)

    def paint(self, painter, option, index):
        pixmap = index.data(Qt.DecorationRole)
        if pixmap:
            rect = option.rect
            scaled_pixmap = pixmap.scaled(rect.width(), rect.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
            x = rect.x() + (rect.width() - scaled_pixmap.width()) / 2
            y = rect.y() + (rect.height() - scaled_pixmap.height()) / 2
            painter.drawPixmap(x, y, scaled_pixmap)
        else:
            super().paint(painter, option, index)


class Table(QTableWidget):
    def __init__(self, rows, columns):
        super().__init__(rows, columns)
        self.setItemDelegate(ImageDelegate(self))

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)


        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        for i in range(rows):
            for j in range(columns):
                if i == 0 and j == 0:  # Add an image to the first cell
                    item = QTableWidgetItem()
                    pixmap = QPixmap('D:\\User\\AaCePbBf.png')  # Replace with the path to your image
                    if not pixmap.isNull():  # Check if the pixmap was successfully created
                        item.setData(Qt.DecorationRole, pixmap)
                    self.setItem(i, j, item)
                else:
                    self.setItem(i, j, QTableWidgetItem(f"({j}, {i})"))

        total_width = sum([self.columnWidth(i) for i in range(self.columnCount())])
        total_height = sum([self.rowHeight(i) for i in range(self.rowCount())])

        # Set the total width and height
        self.setMinimumWidth(total_width)
        self.setMinimumHeight(total_height)


app = QApplication(sys.argv)

scene = QGraphicsScene()

table = Table(10, 10)
proxy = QGraphicsProxyWidget()
proxy.setWidget(table)
proxy.setMinimumSize(table.minimumWidth(), table.minimumHeight())
scene.addItem(proxy)

view = QGraphicsView()
view.setScene(scene)
view.setSceneRect(0, 0, 5000, 5000)
view.show()

sys.exit(app.exec())

我知道问两个问题是不正常的,但是我向表格单元格添加图像的机制可以吗?在我看来,即使是小图像也会由于图像缩放而损失很多质量。

python pyqt pyside
1个回答
0
投票
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QIcon, QPixmap, QBrush
from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsRectItem, QGraphicsTextItem, \
    QTableWidget, QTableWidgetItem, QGraphicsProxyWidget, QStyledItemDelegate
import sys


class ImageDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        super(ImageDelegate, self).__init__(parent)

    def sizeHint(self, option, index):
        icon = index.data(Qt.DecorationRole)
        if icon:
            return QSize(128, 128)  # Set the size of the icon to 128x128 pixels
        else:
            return super().sizeHint(option, index)

    def paint(self, painter, option, index):
        icon = index.data(Qt.DecorationRole)
        if icon:
            rect = option.rect
            icon.paint(painter, rect, Qt.AlignCenter)
        else:
            super().paint(painter, option, index)


class Table(QTableWidget):
    def __init__(self, rows, columns):
        super().__init__(rows, columns)
        self.setItemDelegate(ImageDelegate(self))

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        for i in range(rows):
            for j in range(columns):
                if i == 0 and j == 0:  # Add an image to the first cell
                    item = QTableWidgetItem()
                    pixmap = QPixmap('D:\\User\\10101_gacksung_profile.png')  # Replace with the path to your image
                    if not pixmap.isNull():  # Check if the pixmap was successfully created
                        icon = QIcon(pixmap)
                        item.setData(Qt.DecorationRole, icon)
                    self.setItem(i, j, item)
                else:
                    self.setItem(i, j, QTableWidgetItem(f"({j}, {i})"))

        self.resizeColumnsToContents()
        self.resizeRowsToContents()

        total_width = sum([self.columnWidth(i) for i in
                           range(self.columnCount())]) + self.verticalHeader().width() + 2 * self.frameWidth()
        total_height = sum([self.rowHeight(i) for i in
                            range(self.rowCount())]) + self.horizontalHeader().height() + 2 * self.frameWidth()

        self.setMinimumWidth(total_width)
        self.setMinimumHeight(total_height)


app = QApplication(sys.argv)

scene = QGraphicsScene()

table = Table(15, 15)
proxy = QGraphicsProxyWidget()
proxy.setWidget(table)
scene.addItem(proxy)

view = QGraphicsView()
view.setScene(scene)
view.setSceneRect(0, 0, 5000, 5000)
view.show()

sys.exit(app.exec())

我能够解决这两个问题,尽管我不确定我是否正确且以最佳方式完成了它。 我改变了什么:

  1. 重新设计了最小表格大小计算以考虑标题和框架大小
  2. 使用绘画更改了 QIcon 的图像添加

如果您有任何补充或建议,请写信。

© www.soinside.com 2019 - 2024. All rights reserved.