9

ここに画像の説明を入力してください

上記のウィジェットで2つの問題を解決する必要があります。

  1. 画像に表示されている投稿ウィジェットの間に配置されるスペースの量を定義できるようにしたいと思います(これらはそのままで見栄えがしますが、完了したことを知りたいです)。
  2. テキスト編集を水平方向に拡大せずに、含まれるテキストの量に基づいて垂直方向に拡大したいと思います。

1の場合、ウィジェットに入力するコードは次のとおりです。

self._body_frame = QWidget()
self._body_frame.setMinimumWidth(750)
self._body_layout = QVBoxLayout()
self._body_layout.setSpacing(0)
self._post_widgets = []
for i in range(self._posts_per_page):
    pw = PostWidget()
    self._post_widgets.append(pw)
    self._body_layout.addWidget(pw)

    self._body_frame.setLayout(self._body_layout)

SetSpacing(0)は物事を近づけませんが、SetSpacing(100)はそれを増やします。

編集

(質問2の場合)これについては触れていませんが、親ウィジェットに垂直スクロールバーを持たせたいと思います。

私は自分自身の質問に答えましたが、その言葉遣い、そして原因と影響に基づいています。両方のポイントに対処するための適切に書かれたチュートリアルスタイルの答えは、恩恵を受けます:D

編集2

以下の私自身の答えを使用して、私は問題を解決しました。私は今、自分の答えを受け入れます。

ここに画像の説明を入力してください

4

2 に答える 2

13

1) レイアウト

ここでの他の回答は非常に不明確であり、レイアウトの余白がどのように機能するかについておそらくオフです。実際には非常に簡単です。

  1. レイアウトにはコンテンツ マージンがあります
  2. ウィジェットにはコンテンツ マージンがあります

これらは両方とも、内容の周囲にパディングを定義します。レイアウトのマージン設定 2 は、すべての辺に 2 ピクセルのパディングを意味します。親子のウィジェットとレイアウトがある場合 (UI を構成するときは常にそうです)、各オブジェクトは、個別に有効になる特定のマージンを指定できます。つまり... マージンを 2 に指定する親レイアウトと、マージンを 2 に指定する子レイアウトを使用すると、実質的に 4 ピクセルのマージンが表示されます (明らかに、ウィジェットにフレームがある場合、その間に何らかのフレーム描画が行われます)。

簡単なレイアウトの例はこれを示しています:

w = QtGui.QWidget()
w.resize(600,400)

layout = QtGui.QVBoxLayout(w)
layout.setMargin(10)
frame = QtGui.QFrame()
frame.setFrameShape(frame.Box)
layout.addWidget(frame)

layout2 = QtGui.QVBoxLayout(frame)
layout2.setMargin(20)
frame2 = QtGui.QFrame()
frame2.setFrameShape(frame2.Box)
layout2.addWidget(frame2)

レイアウトイメージ例

最上位の余白は各辺で 10、子レイアウトは各辺で 20 であることがわかります。数学に関しては特に複雑なことはありません。

マージンは、サイドごとに指定することもできます。

# left: 20, top: 0, right: 20, bottom: 0
layout.setContentsMargins(20,0,20,0)

レイアウトに間隔を設定するオプションもあります。間隔は、レイアウトの各子の間に配置されるピクセル量です。これを 0 に設定すると、それらが互いに正反対であることを意味します。スペースはレイアウトの特徴であり、マージンはオブジェクト全体の特徴です。レイアウトには、周囲にマージンを設定したり、子の間にスペースを設定したりできます。また、ウィジェットの子は、個々の表示の一部である独自のマージンを持つことができます。

layout.setSpacing(10) # 10 pixels between each layout item

2) QTextEdit の自動サイズ変更

次に、質問の 2 番目の部分です。自動サイズ変更 QTextEdit を作成するにはいくつかの方法があると確信しています。しかし、これにアプローチする 1 つの方法は、ドキュメント内のコンテンツの変更を監視し、ドキュメントの高さに基づいてウィジェットを調整することです。

class Window(QtGui.QDialog):

    def __init__(self):
        super(Window, self).__init__()
        self.resize(600,400)

        self.mainLayout = QtGui.QVBoxLayout(self)
        self.mainLayout.setMargin(10)

        self.scroll = QtGui.QScrollArea()
        self.scroll.setWidgetResizable(True)
        self.scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.mainLayout.addWidget(self.scroll)

        scrollContents = QtGui.QWidget()
        self.scroll.setWidget(scrollContents)

        self.textLayout = QtGui.QVBoxLayout(scrollContents)
        self.textLayout.setMargin(10)

        for _ in xrange(5):
            text = GrowingTextEdit()
            text.setMinimumHeight(50)
            self.textLayout.addWidget(text)


class GrowingTextEdit(QtGui.QTextEdit):

    def __init__(self, *args, **kwargs):
        super(GrowingTextEdit, self).__init__(*args, **kwargs)  
        self.document().contentsChanged.connect(self.sizeChange)

        self.heightMin = 0
        self.heightMax = 65000

    def sizeChange(self):
        docHeight = self.document().size().height()
        if self.heightMin <= docHeight <= self.heightMax:
            self.setMinimumHeight(docHeight)

QTextEdit->をサブクラスGrowingTextEdit化し、そのドキュメントから発せられる信号をsizeChange、ドキュメントの高さをチェックするスロットに接続しました。また、heightMin および heightMax 属性を含めて、自動拡張を許可する大きさまたは小ささを指定できるようにしました。これを試してみると、ボックスに入力すると、ウィジェットのサイズが自動的に変更され、行を削除すると縮小されることがわかります。必要に応じてスクロールバーをオフにすることもできます。現在、各テキスト編集には、親のスクロール領域に加えて、独自のバーがあります。docHeightまた、小さなパッド値を追加して、コンテンツのスクロールバーが表示されないように拡張できると思います。

このアプローチは、実際には低レベルではありません。一般的に公開されているシグナルとウィジェットの子メンバーを使用して、状態変化の通知を受け取ります。既存のウィジェットの機能を拡張するためにシグナルを利用するのはかなり一般的です。

自動拡張ウィジェットのサンプル画像

于 2012-08-01T17:29:57.203 に答える
1

質問 1 に対処するには:

親ウィジェットとレイアウトには、レイアウト自体の間隔パラメーターに加えて、マージンがあります。いくつかの因果関係テストから、マージンが親の外側領域と内側領域の両方に適用されることが明らかです。

たとえば、親に 2 ピクセルの余白が指定されている<--2 pixel | 2 pixel -->場合、レイアウト (この場合は HBoxLayout) の余白に加えて、垂直境界線に余白があります。レイアウトに 2 ピクセルのマージンがあり、水平線の周りの領域は次のようになります。

<-- 2 pixel | 2 pixel --> <-- 2 pixel (L) 2 pixel--> (W)

編集おそらく次のようになります。| 2 pixel --> (L) 2 pixel --> <-- 2 pixel (W)

|(L)垂直線はレイアウトの垂直線であり(W)、水平レイアウトの埋め込みウィジェットの境界線です。

レイアウトの間隔は、レイアウトのマージンに加えて、レイアウトのウィジェット間に挿入されるスペースの量を制御する追加パラメーターです。

上記の説明は正確ではない可能性があります (不正確な場合は自由に編集してください) が、親とレイアウトのマージンをゼロに設定し、レイアウトの間隔をゼロに設定すると、目的の結果が得られます。

ポイント 2 の場合:

この問題に対処する簡単な方法はないと思います (API のより深い理解を必要とする、より低いレベルでの接続に頼らなければならない可能性があります)。QLabelウィジェットの代わりにウィジェットを使用する必要があると思いますQTextEdit。ラベルにはビューがないため、必要に応じて拡張されます。少なくとも、親がその動きに制約されていない限り、ラベルはデフォルトで機能します。

したがって、を変更しQTextEditQlabelスクロール ビューを親に追加すると、すべてが思い通りに機能するはずです。QTextEdit背景で選んだような気がします。HTML が QT ウィジェットでどのように機能するかを調べれば、HTML を介して背景を変更できるかもしれません。

編集

ここに画像の説明を入力

このウィジェット (サイズはご容赦ください) は、PyQT を使用する OS X で次のコードによって作成されます。

import sys
from PyQt4 import Qt

class PostMeta(Qt.QWidget):
    posted_at_base_text = "<b> Posted At:</b>"
    posted_by_base_text = "<b> Posted By:</b>"

    def __init__(self):
        Qt.QWidget.__init__(self)
        self._posted_by_label = Qt.QLabel()
        self._posted_at_label = Qt.QLabel()
        layout = Qt.QVBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(5)
        layout.addWidget(self._posted_by_label)
        layout.addWidget(self._posted_at_label)
        layout.addStretch()
        self.setLayout(layout)
        self._posted_by_label.setText(PostMeta.posted_by_base_text)
        self._posted_at_label.setText(PostMeta.posted_at_base_text)


class FramePost(Qt.QFrame):
    def __init__(self):
        Qt.QFrame.__init__(self)
        layout = Qt.QHBoxLayout()
        layout.setMargin(10)
        self.te = Qt.QLabel()
        self.te.setStyleSheet("QLabel { background : rgb(245,245,245) }")
        self.te.setFrameStyle( Qt.QFrame.Panel |  Qt.QFrame.Sunken)
        self.te.setLineWidth(1)
        self._post_meta = PostMeta()
        layout.addWidget(self._post_meta)
        vline = Qt.QFrame()
        vline.setFrameShape(Qt.QFrame.VLine)
        layout.addWidget(vline)
        layout.addWidget(self.te)
        self.te.setText(
            """            line one
            line two
            line three
            line four
            line five
            line six
            line seven
            line eight
            line nine
            line ten
            line eleven
            line twelve
            line thirteen""")
        self.setLayout(layout)

        self.setFrameStyle(Qt.QFrame.Box)
        self.setLineWidth(2)

app = Qt.QApplication(sys.argv)
w = Qt.QWidget()
layout = Qt.QHBoxLayout()
fp = FramePost()
layout.addWidget(fp)
w.setLayout(layout)
w.show()
app.exec_()

左のウィジェットのラベルは、スペーサーとマージンの微調整が行われたことを示していQLabelます。投稿テキストには を使用しました。ラベルを微調整して、デフォルトのように見えることに注意してください。QTextEdit

于 2012-07-31T22:18:36.750 に答える