【问题标题】:QGraphicsLayout - Unexpected Extra Spacing Between ItemsQGraphicsLayout - 项目之间的意外额外间距
【发布时间】:2013-07-01 06:23:05
【问题描述】:

我正在使用 QGraphics Framework 编写一些原型。我在模拟常规布局时遇到了麻烦。

这两个小部件之间的间距很大,但我已经将所有可能的间距设置为 0。需要注意的是,我正在使用 Awesome Windows 管理器,因此窗口周围没有任何边框。

这是我的代码(抱歉,应该更短):

import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import Qt


class PixmapLayoutItem(QtGui.QGraphicsLayoutItem):

    def __init__(self, image, parent=None):
        super(PixmapLayoutItem, self).__init__(parent)
        self.pixmapItem = QtGui.QGraphicsPixmapItem()
        self.pixmapItem.setPixmap(QtGui.QPixmap(image))
        self.setGraphicsItem(self.pixmapItem)
        print(self.pixmapItem.boundingRect().size(),
              self.pixmapItem.pixmap().size())

    def sizeHint(self, which, constraint=QtCore.QSizeF()):
        return self.pixmapItem.boundingRect().size()

    def setGeometry(self, rect):
        self.pixmapItem.setPos(rect.topLeft())


class TextLayoutItem(QtGui.QGraphicsLayoutItem):

    def __init__(self, text, parent=None):
        super(TextLayoutItem, self).__init__(parent)
        self.textItem = QtGui.QGraphicsTextItem()
        self.textItem.setHtml(text)
        self.setGraphicsItem(self.textItem)
        print(self.textItem.boundingRect().size())

    def sizeHint(self, which, constraint=QtCore.QSizeF()):
        return self.textItem.boundingRect().size()

    def setGeometry(self, rect):
        self.textItem.setPos(rect.topLeft())


class MainWindow(QtGui.QGraphicsView):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        mainLayout = QtGui.QGraphicsLinearLayout()
        mainLayout.setSpacing(0)

        avatar = self._avatar()
        mainLayout.addItem(avatar)
        mainLayout.setAlignment(avatar, Qt.AlignCenter)

        text = self._text()
        mainLayout.addItem(text)
        mainLayout.setAlignment(text, Qt.AlignCenter)

        mainWidget = QtGui.QGraphicsWidget()
        mainWidget.setLayout(mainLayout)

        scene = QtGui.QGraphicsScene()
        scene.addItem(mainWidget)
        self.setScene(scene)

    @staticmethod
    def _avatar():
        pixmap = PixmapLayoutItem("./avatar.jpg")
        text = TextLayoutItem("Hello, world!")

        avatarLayout = QtGui.QGraphicsLinearLayout()
        avatarLayout.setOrientation(Qt.Vertical)
        avatarLayout.setSpacing(0)

        avatarLayout.addItem(pixmap)
        avatarLayout.setAlignment(pixmap, Qt.AlignCenter)

        avatarLayout.addItem(text)
        avatarLayout.setAlignment(text, Qt.AlignCenter)

        avatarWidget = QtGui.QGraphicsWidget()
        avatarWidget.setWindowFrameMargins(0, 0, 0, 0)
        avatarWidget.setContentsMargins(0, 0, 0, 0)
        avatarWidget.setLayout(avatarLayout)

        return avatarWidget

    @staticmethod
    def _text():
        text = TextLayoutItem("UNIX - Where is a shell, where is a way.")
        return text


if __name__ == "__main__":
    App = QtGui.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    App.exec()

我不知道问题的根源是什么。

谢谢。

【问题讨论】:

  • 我只是在这里猜测,但这可能是一些布局拉伸问题。尝试将scene's rect 更改为较小的,看看是否会减小间隙的大小。
  • 我们说的是同一件事吗? Unexpected Extra Spacing 表示avatarWidget 和文本之间的空格。
  • 是的,我们是。但没关系,我尝试制作类似的东西,但跳过QGraphicsLayoutItems 并改用QGraphicsWidgets,它对我有用。 QGraphicsLayout::setContentsMargins 是我必须用来消除差距的唯一功能。
  • 这对我不起作用:(
  • 你可以试试我做的。跳过QGraphicsLayoutItems 并使用包含QLabelsQGraphicsWidget,看看是否有什么不同。

标签: qt layout user-interface pyqt


【解决方案1】:

_avatar函数中改行:

avatarWidget.setContentsMargins(0, 0, 0, 0)

avatarLayout.setContentsMargins(0, 0, 0, 0)

间距将从这里开始:

到这里:

不知道这对你来说是否足够小,但它消除了大部分差距。

更新

使用较小的像素图,您会看到图像和 UNIX 文本之间存在间隙,因为“Hello world!”文本比像素图更宽(我用黑色突出显示了头像小部件边框):

使文本更短将使头像小部件更小并失去明显的差距:

【讨论】:

  • 感谢您的了解 :)
  • 糟糕。它仅在图像足够小时才有效:(试试这个:blog001.oss.aliyuncs.com/avatar.jpg
  • 如果图像比它下面的文本小,那么它会使整个小部件变宽。这将显示为图像和“Unix ..”文本之间的额外间隙。我用一些图片更新了我的答案。