1

解決しようとしているいくつかの問題があり、理解できません。私はこれまであまり作業したことがありませんが、画像をロードしようとしている をQGraphicsView作成し、を使用して、画像が行ごとに使用する列の数を動的に制御しようとしています。たとえば、16 個の画像があり、「デフォルトで持っている」4 に設定されている場合、4 行 4 列の画像が必要です。その部分は問題なく動作しているようですが、コードはあまり良くありません。カウントが変わるたびにそれらをすべて削除して再ロードしない限り、画像の列と行の数を制御する方法がわかりませんでした。アイテムを個別に削除するのに苦労したため、シーン全体をクリアしてすべてをリロードすることになりました。 QGraphicsViewQSpinBoxQSpinBox

私が今抱えている主な問題は、行と列の四角形を正しく自動的に設定することです。スクロールバーに空のスペースを残さずに、変更に合わせてシーンのサイズを変更しようとしています。

画像がロードされたときの開始時の様子を次に示します。

読み込まれた画像

QSpinBox少しスクロールするとこんな感じ。この時点では、空のスペースがたくさんある水平スクロールバーではなく、垂直スクロールバーのみが存在するはずです。

不要なスクロールバー

いくつかの試行錯誤の後、コードでこのようにシーンの四角形を設定できることがわかりましself.scene.setSceneRect(QRectF(self.graphics_widget.rect()))た。スクロールバーの問題を修正するために完全に機能しているように見えますが、何らかの方法で手動でトリガーした場合にのみ機能させることができ、この例では「Set Rect」ボタンの機能です。

ここに例があります。[Set Rect] ボタンをクリックすると、垂直スクロールバーが正しく削除され、水平スクロールバーが行全体の正確な幅になります。

適切な四角形

すべてが読み込まれた後にシーンの四角形を自動的に設定しようとすると、間違った幅と高さが得られますが、ボタンなどで手動で設定すると、何らかの理由で正しく機能します。

私が抱えている他の小さな問題は、上部の赤いバーがビューポート領域よりもさらに伸びることです。水平スクロールバーが表示されているときに水平にスクロールしようとすると、このようになり、幅全体を伸ばしたいと思います。

醜いトップバー

それは大したことではありませんが、私はそれを理解できると確信しています。私の主な関心事は、シーンの四角形を自動的に設定して、スクロールバーに空のスペースを残さずにすべてが正しく流れるようにすることです。
誰か提案はありますか?ありがとう。

これが私のコードです:

from PySide2.QtCore import QRectF, QSizeF, QRect, Qt, QPointF
from PySide2.QtGui import QPixmap, QFont, QColor, QPen, QBrush
from PySide2.QtWidgets import QGraphicsWidget, QWidget, QVBoxLayout, QPushButton, QHBoxLayout, \
    QSpinBox, QGraphicsView, QGraphicsScene, QGraphicsGridLayout, QApplication


class PixmapItem(QGraphicsWidget):
    def __init__(self, image, parent=None):
        super(PixmapItem, self).__init__(parent)
        self.pic = QPixmap(image)
        self._boundingRect = QRectF()
        self.pic_size = self.pic.rect().size()

    def boundingRect(self):
        width = self.pic_size.width()
        height = self.pic_size.height()
        pix_rect = QRectF(0.0, 0.0, width, height)
        self._boundingRect = pix_rect
        return pix_rect

    def sizeHint(self, which, constraint=QSizeF()):
        return self._boundingRect.size()

    def paint(self, painter, option, widget):
        painter.drawPixmap(QRect(0, 40, self.pic_size.width(), self.pic_size.height()), self.pic, self.pic.rect())

class MyScene(QGraphicsScene):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def drawBackground(self, painter, rect):
        bg_brush = QBrush(QColor(255, 255, 255), Qt.SolidPattern)
        painter.fillRect(rect, bg_brush)
        #Red bar on top
        painter.setPen(QPen(Qt.NoPen))
        brush = QBrush(QColor(139, 0, 0), Qt.SolidPattern)
        r = QRectF(QPointF(0, 0), QSizeF(rect.width(), 30))
        painter.fillRect(r, brush)
        self.update()

class Widget(QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.resize(330, 330)
        self.imglist = ["py.png", "py.png","py.png","py.png","py.png","py.png",
                        "py.png","py.png","py.png","py.png","py.png","py.png"]

        self._layout = QVBoxLayout()
        self._layout2 = QHBoxLayout()

        self.btn = QPushButton("Load")
        self.column_spinbox = QSpinBox()
        self.column_spinbox.setRange(1, 25)
        self.column_spinbox.setValue(4)
        self.column_spinbox.setSingleStep(1)
        self.btn2 = QPushButton("Set Rect")

        self._layout2.addWidget(self.btn)
        self._layout2.addWidget(self.column_spinbox)
        self._layout2.addWidget(self.btn2)
        self._layout.addLayout(self._layout2)

        self._layout3 = QHBoxLayout()
        self.view = QGraphicsView()
        self.view.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.scene = MyScene()
        self.view.setScene(self.scene)
        self.graphics_widget = QGraphicsWidget()
        self.scene.addItem(self.graphics_widget)
        self.graphics_layout = QGraphicsGridLayout()
        self.graphics_widget.setLayout(self.graphics_layout)
        self._layout3.addWidget(self.view)
        self._layout.addLayout(self._layout3)
        self.setLayout(self._layout)
        self.btn.clicked.connect(self._load_pix)
        self.btn2.clicked.connect(self._set_rect)
        self.column_spinbox.valueChanged.connect(self.set_columns)

    def _set_rect(self):
        self.scene.setSceneRect(QRectF(self.graphics_widget.rect()))

    def _load_pix(self):
        for img in range(len(self.imglist)):
            pixmap = PixmapItem(self.imglist[img])
            row, column = divmod(img, self.column_spinbox.value())
            self.graphics_layout.addItem(pixmap, row, column)
            self.graphics_layout.setColumnSpacing(column, 15)
            self.graphics_layout.setRowSpacing(row, 15)
        self.scene.setSceneRect(QRectF(self.graphics_widget.rect()))
        # Add text to top
        item = self.scene.addText("Some Sample Text.", QFont("Arial", 16, QFont.Light))
        item.setDefaultTextColor(QColor(255, 255, 255))

    def set_columns(self):
        self.view.scene().clear()
        #After clearing the scene, re-add the widgets
        self.graphics_widget = QGraphicsWidget()
        self.scene.addItem(self.graphics_widget)
        self.graphics_layout = QGraphicsGridLayout()
        self.graphics_widget.setLayout(self.graphics_layout)
        for img in range(len(self.imglist)):
            pixmap = PixmapItem(self.imglist[img], self.graphics_widget)
            row, column = divmod(img, self.column_spinbox.value())
            self.graphics_layout.addItem(pixmap, row, column)
            self.graphics_layout.setColumnSpacing(column, 15)
            self.graphics_layout.setRowSpacing(row, 15)
        self.scene.setSceneRect(QRectF(self.graphics_widget.rect()))
        #Add text to top again
        item = self.scene.addText("Some Sample Text.", QFont("Arial", 16, QFont.Light))
        item.setDefaultTextColor(QColor(255, 255, 255))

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    widget = Widget()
    widget.show()
    app.exec_()
4

1 に答える 1