【问题标题】:Is there a way to overlay multiple items on a parent widget (PySide/Qt)有没有办法在父小部件上覆盖多个项目(PySide/Qt)
【发布时间】:2014-07-18 03:49:38
【问题描述】:

我有一个主要的父窗口小部件,我希望在父窗口小部件之上有几个布局。

使用父窗口小部件初始化布局会将布局放置在父窗口小部件之上。我喜欢这样,并希望为同一个父小部件多次(左侧、顶部、底部和右侧)。

我使用了具有不同子布局的 QGridLayout,但这会导致布局调整大小并迫使它们变小。最后添加的任何叠加层都应该在其他项目之上。

下面是我想要的一个非常简单的例子。

import sys
from PySide import QtGui, QtCore


class Overlay(QtGui.QBoxLayout):
    """Overlay widgets on a parent widget."""

    def __init__(self, parent=None, location="left"):
        super().__init__(QtGui.QBoxLayout.TopToBottom, parent)

        if location == "left" or location == "right":
            self.setDirection(QtGui.QBoxLayout.TopToBottom)
            if location == "right":
                self.setAlignment(QtCore.Qt.AlignRight)
        elif location == "top" or location == "bottom":
            self.setDirection(QtGui.QBoxLayout.LeftToRight)
            if location == "bottom":
                self.setAlignment(QtCore.Qt.AlignBottom)

        self.css = "QWidget {background-color: lightskyblue; color: white}"
    # end Constructor

    def addWidget(self, widget):
        super().addWidget(widget)

        widget.setStyleSheet(self.css)
    # end addWidget
# end class Overlay

def main():
    app = QtGui.QApplication(sys.argv)

    window = QtGui.QMainWindow()
    window.show()

    widg = QtGui.QTreeView()
    window.setCentralWidget(widg)

    left = Overlay(widg, "left")
    left.addWidget(QtGui.QLabel("HELLO"))
    left.addWidget(QtGui.QLabel("WORLD!"))

    top = Overlay(widg, "top")
    top.addWidget(QtGui.QLabel("Hello"))
    top.addWidget(QtGui.QLabel("World!"))

    right = Overlay(location="right")
    right.setParent(widg)
    right.addWidget(QtGui.QLabel("hello"))
    right.addWidget(QtGui.QLabel("world!"))

    return app.exec_()
# end main

if __name__ == '__main__':
    sys.exit(main())

是否有多个布局具有相同的父级?如果没有,是否有某种方法可以创建一个虚拟小部件,该小部件将与父小部件一起移动并让叠加层使用多个虚拟小部件作为其父小部件?

还有

layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom, parent_widget)

不做同样的事情

layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom)
layout.setParent(parent_widget)

初始化对不同的父级做了什么?

【问题讨论】:

    标签: qt pyqt pyside


    【解决方案1】:

    我通过创建自己的主自定义布局解决了这个问题。 OverlayCenter 将主小部件作为其父小部件,您只需将其他布局添加到此布局。

    import sys
    from PySide import QtGui, QtCore
    
    
    class OverlayCenter(QtGui.QLayout):
        """Layout for managing overlays."""
    
        def __init__(self, parent):
            super().__init__(parent)
    
            # Properties
            self.setContentsMargins(0, 0, 0, 0)
    
            self.items = []
        # end Constructor
    
        def addLayout(self, layout):
            """Add a new layout to overlay on top of the other layouts and widgets."""
            self.addChildLayout(layout)
            self.addItem(layout)
        # end addLayout
    
        def __del__(self):
            """Destructor for garbage collection."""
            item = self.takeAt(0)
            while item:
                item = self.takeAt(0)
        # end Destructor
    
        def addItem(self, item):
            """Add an item (widget/layout) to the list."""
            self.items.append(item)
        # end addItem
    
        def count(self):
            """Return the number of items."""
            return len(self.items)
        # end Count
    
        def itemAt(self, index):
            """Return the item at the given index."""
            if index >= 0 and index < len(self.items):
                return self.items[index]
    
            return None
        # end itemAt
    
        def takeAt(self, index):
            """Remove and return the item at the given index."""
            if index >= 0 and index < len(self.items):
                return self.items.pop(index)
    
            return None
        # end takeAt
    
        def setGeometry(self, rect):
            """Set the main geometry and the item geometry."""
            super().setGeometry(rect)
    
            for item in self.items:
                item.setGeometry(rect)
        # end setGeometry
    # end class OverlayCenter
    
    
    class Overlay(QtGui.QBoxLayout):
        """Overlay widgets on a parent widget."""
    
        def __init__(self, location="left", parent=None):
            super().__init__(QtGui.QBoxLayout.TopToBottom, parent)
    
            if location == "left":
                self.setDirection(QtGui.QBoxLayout.TopToBottom)
                self.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
            elif location == "right":
                self.setDirection(QtGui.QBoxLayout.TopToBottom)
                self.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
            elif location == "top":
                self.setDirection(QtGui.QBoxLayout.LeftToRight)
                self.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter)
            elif location == "bottom":
                self.setDirection(QtGui.QBoxLayout.LeftToRight)
                self.setAlignment(QtCore.Qt.AlignBottom | QtCore.Qt.AlignHCenter)
    
    
            self.css = "QWidget {background-color: lightskyblue; color: white}"
        # end Constructor
    
        def addWidget(self, widget):
            super().addWidget(widget)
    
            widget.setStyleSheet(self.css)
        # end addWidget
    # end class Overlay
    
    def main():
        app = QtGui.QApplication(sys.argv)
    
        window = QtGui.QMainWindow()
        window.show()
    
        widg = QtGui.QTreeView()
        window.setCentralWidget(widg)
    
        left = Overlay("left")
        lhlbl = QtGui.QLabel("Hello")
        lwlbl = QtGui.QLabel("World!")
        lhlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        lwlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        left.addWidget(lhlbl)
        left.addWidget(lwlbl)
    
        top = Overlay("top")
        lhlbl = QtGui.QLabel("HELLO")
        lwlbl = QtGui.QLabel("WORLD!")
        lhlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        lwlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        top.addWidget(lhlbl)
        top.addWidget(lwlbl)
    
        right = Overlay("right")
        lhlbl = QtGui.QLabel("hellO")
        lwlbl = QtGui.QLabel("worlD!")
        lhlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        lwlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        right.addWidget(lhlbl)
        right.addWidget(lwlbl)
    
        bottom = Overlay("bottom")
        lhlbl = QtGui.QLabel("hello")
        lwlbl = QtGui.QLabel("world!")
        lhlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        lwlbl.setSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Maximum)
        bottom.addWidget(lhlbl)
        bottom.addWidget(lwlbl)
    
        center = OverlayCenter(widg)
        center.addLayout(left)
        center.addLayout(top)
        center.addLayout(right)
        center.addLayout(bottom)
    
        return app.exec_()
    # end main
    
    if __name__ == '__main__':
        sys.exit(main())
    

    【讨论】:

      猜你喜欢
      • 2014-02-01
      • 2017-10-31
      • 2015-04-18
      • 1970-01-01
      • 2010-12-09
      • 2018-08-10
      • 1970-01-01
      • 2019-03-12
      • 1970-01-01
      相关资源
      最近更新 更多