0

アプリケーション内に QWidget (content_widget) を持つ QScrollArea があります。アプリケーションの実行中に画像で塗りつぶしたい。画像の数がスクロールせずに表示できる数を超える場合は、スクロール動作が必要です。私はここまで来ました:

children_occupied_width = self.ui.content_widget.childrenRect().width()

image_view = QtGui.QGraphicsView(self.ui.content_widget)
image_view.setGeometry(QtCore.QRect( children_occupied_width, 0, 210, 210 ))
image_view.setObjectName("New Image")

placeholder_image = QtGui.QGraphicsScene()
placeholder_image.addPixmap(QtGui.QPixmap('placeholder.png'))
image_view.setScene(placeholder_image)

image_view.show()

画像はリストの正しい位置に表示されますが、画像が表示領域の外に配置され始めるとスクロールしません。を使っても content_widget のサイズは変わらないようです

self.ui.content_widget.resize(...)

また

self.ui.content_widget.adjustSize()

成長/サイズ変更する方法は?

4

2 に答える 2

1

この最初の部分は、本当に必要なものではないことが判明しました。情報提供のために残していますが、下部の更新を参照してください

問題は、QGraphicsView 自体が一種のスクロール ウィジェットであり、表示しているシーンのスライスを表すことです。ビューを単独で使用し、独自のスクロールバーを利用するのが理想的です。

ただし、ビューのコンテンツ サイズを通常の QWidget スクロールに転送する必要がある場合は、シーンのコンテンツが変更されたときに QGraphicsView のサイズを常に変更する必要があります。QScrollArea は、設定されているウィジェットのサイズ変更にのみ応答します。ビューのサイズを変更する必要があります。プロセスは、ビューが追加または削除されたアイテムのシーンからの信号をリッスンし、それらのすべての子を完全に囲むようにサイズを変更する必要があるというものです。

以下は、QGraphicsView ウィジェットが単独でスクロール機能として完全に機能する方法の例です。

from PyQt4 import QtCore, QtGui

app = QtGui.QApplication([])
scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView()
view.setScene(scene)

view.resize(600,300)

pix = QtGui.QPixmap("image.png")

w,h = pix.width(), pix.height()
x = y = 0
pad = 5
col = 3

for i in xrange(1,20):
    item = scene.addPixmap(pix)
    item.setPos(x,y)

    if i % col == 0:
        x = 0
        y += h+pad
    else:
        x+=w+pad

view.show()
view.raise_()
app.exec_()

画像がビューの現在のサイズを超えると、スクロールバーが表示されることがわかります。
ビューのスクロールとして機能する親スクロール領域が本当に必要な場合 (理由はよくわかりません)、シーンで何らかのイベントを監視し、常に監視する必要がある方法を示すより複雑な例を次に示します。ビューのサイズを更新して、親スクロール領域にスクロールバーを強制します。rect が変更されたとき (子が追加されたとき) に、シーンでシグナルを監視することを選択しました。

from PyQt4 import QtCore, QtGui

app = QtGui.QApplication([])

win = QtGui.QDialog()
win.resize(600,300)
layout = QtGui.QVBoxLayout(win)
scroll = QtGui.QScrollArea()
scroll.setWidgetResizable(True)
layout.addWidget(scroll)

view = QtGui.QGraphicsView(scroll)
view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scene = QtGui.QGraphicsScene(scroll)
view.setScene(scene)

scroll.setWidget(view)

pix = QtGui.QPixmap("image.png")

w,h = pix.width(), pix.height()
x = y = i = 0
pad = 5
col = 3

def createImage():
    global x,y,i
    item = scene.addPixmap(pix)
    item.setPos(x,y)

    i+=1
    if i % col == 0:
        x = 0
        y += h+pad
    else:
        x+=w+pad

def changed():
    size = scene.itemsBoundingRect().size()
    view.setMinimumSize(size.width()+pad, size.height()+pad)

scene.changed.connect(changed)

t = QtCore.QTimer(win)
t.timeout.connect(createImage)
t.start(500)

win.show()
win.raise_()
app.exec_()

スクロール領域は、子として設定されているウィジェットのサイズを常に見ています。ビューのサイズを変更する必要があります。

アップデート

コメントからわかるように、このアプローチでは QGraphics オブジェクトを実際に使用する必要はありませんでした。それはあなたの仕事をより複雑にするだけでした。垂直レイアウトを使用して、QLabel ウィジェットを追加するだけです。

from PyQt4 import QtCore, QtGui

app = QtGui.QApplication([])

win = QtGui.QDialog()
win.resize(300,300)
layout = QtGui.QVBoxLayout(win)
scroll = QtGui.QScrollArea()
scroll.setWidgetResizable(True)
layout.addWidget(scroll)

scrollContents = QtGui.QWidget()
layout = QtGui.QVBoxLayout(scrollContents)
scroll.setWidget(scrollContents)

pix = QtGui.QPixmap("image.png")

def createImage():
    label = QtGui.QLabel()
    label.setPixmap(pix)
    layout.addWidget(label)

t = QtCore.QTimer(win)
t.timeout.connect(createImage)
t.start(500)

win.show()
win.raise_()
app.exec_()
于 2012-07-15T16:55:58.130 に答える
0

resize私のコードで機能しなかった理由が少なくとも見つかりました。widgetResizableQScroll 領域のプロパティを false に設定する (または Qt Designer で無効にする) と、機能しました。

于 2012-07-18T19:25:26.757 に答える