PySide Qt的:在垂直布局小窗口之间自动垂直生长为文本编辑窗口小部件,并且间隔(PySide

2019-06-26 13:48发布

我需要解决两个问题,我上面的部件。

  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

用我自己的答案下面我已经解决了这个问题。 我会现在开始接受我自己的答案。

Answer 1:

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

现在,你的问题的第二部分。 有几个方法可以创建一个自动调整大小的QTextEdit我相信。 但接近它的一种方法是基于文档的高度看文档中内容的变化,然后调整窗口小部件:

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使其扩展刚好够不显示内容滚动条。

这种方法是不是真的很低的水平。 它采用了常见的暴露信号和控件的子成员为您收到的状态变化的通知。 它很常见的利用信号的扩展现有控件的功能。



Answer 2:

要地址问题1:

家长部件和布局都有利润,除了布局本身的间距参数。 从一些原因和影响测试是apprent,利润率既适用于父的外部区域,以及一个内部区域。

所以,例如,如果2像素余量被指定为亲本的垂直边界具有<--2 pixel | 2 pixel --> <--2 pixel | 2 pixel -->余量除了布局(A HBoxLayout在这种情况下)的边缘。 如果布局具有2像素保证金以及围绕水平线的区域将如下所示:

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

编辑也许它更像是这样的: | 2 pixel --> (L) 2 pixel --> <-- 2 pixel (W) | 2 pixel --> (L) 2 pixel --> <-- 2 pixel (W)

| 是父的垂直线(L)是在布局和的垂直线(W)是在水平布局嵌入式微件的边界。

布局的间距是控制多少空间插入除了任何布局边距布局的小部件之间的附加参数。

上面的描述可能是不准确的(可以随意编辑,它是不准确的),但设置了家长和布局的利润率为布局间距0生成结果你后零。

对于第2点:

我不认为这是解决这一问题(你可能不得不求助于在一个较低的水平,这需要API更深入的了解,以钩住在)一个直接的方式。 我想你应该使用QLabel控件代替的QTextEdit部件。 标签不具有一个视图,从而按需扩展,至少这就是他们在默认情况下是如何工作的,只要父母不限制在它的运动。

因此,改变QTextEditQlabel并添加滚动视图父,一切都应该工作,只要你想。 我中有你选择了一个感觉QTextEdit因为它的背景。 研究HTML工作在QT部件的方式,你也许能够改变通过HTML的背景。

编辑

该窗口小部件(借口的大小)由在OS X下面的代码与PyQt的创建:

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



文章来源: PySide Qt: Auto vertical growth for TextEdit Widget, and spacing between widgets in a vertical layout