Qt Designer 使小部件在布局中与另一个小部件重叠

Posted

技术标签:

【中文标题】Qt Designer 使小部件在布局中与另一个小部件重叠【英文标题】:Qt Designer make widget overlap another widget in layout 【发布时间】:2020-01-21 10:21:43 【问题描述】:

我想使用 Qt Designer 和 PyQt 制作如上图所示的 3 个窗口按钮(类似 Google Chrome)。

我想要 3 个按钮重叠在 TabWidget 的右侧。 但是我只能在像图片一样中断布局时重叠 TabWidget 上的 Button。

当我设置任何布局时,每个小部件都不能相互重叠。 那么设置布局时可以重叠吗?谢谢。

这是我想要的布局

它类似于谷歌浏览器的布局

【问题讨论】:

布局的重点是以预定义的、用户友好的方式放置小部件。通常人们不会重叠小部件。如果您想这样做,有多种选择,包括自己在所有内容之上绘制小部件,不包括您想要从布局中重叠其余部分并手动定位的小部件等。 感谢@rbaleksandar!你有什么例子吗。我是 Qt 的初学者。 我提出的第二个建议应该很简单:只是不要将小部件添加到现有布局中。使用QWidget::move(...) 手动定位小部件。绘制小部件更高级,所以我不推荐它。无论如何,通常您不会手动定位东西,因为您需要考虑许多其他因素(主要是调整大小等事件),布局会脱离您的手。考虑以不涉及此类操作的方式重新设计您的想法。 谢谢@rbaleksandar,我已经完成了。 【参考方案1】:

这不能在创建者/设计者中完成,只能在您的代码中使用setCornerWidget() 来实现。

由于每个角只能设置一个小部件,因此您必须创建一个充当容器的 QWidget,然后将按钮添加到其中。

class Test(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        # ...

        self.createButtons()

    def createButtons(self):
        # create the container and its layout
        self.buttonContainer = QtWidgets.QWidget()
        buttonLayout = QtWidgets.QHBoxLayout(self.buttonContainer)

        # remove margins around the layout and set a minimal spacing between
        # the children widgets
        buttonLayout.setContentsMargins(0, 0, 0, 0)
        buttonLayout.setSpacing(1)

        # QToolButtons are usually better for this, as QPushButtons tend
        # to expand themselves
        self.minimizeButton = QtWidgets.QToolButton(text='_')
        self.maximizeButton = QtWidgets.QToolButton(text='o')
        self.closeButton = QtWidgets.QToolButton(text='x')
        buttonLayout.addWidget(self.minimizeButton)
        buttonLayout.addWidget(self.maximizeButton)
        buttonLayout.addWidget(self.closeButton)

        # set the container as the corner widget; as the docs explain,
        # despite using "TopRightCorner", only the horizontal element (right
        # in this case) will be used 
        self.tabWidget.setCornerWidget(
            self.buttonContainer, QtCore.Qt.TopRightCorner)

【讨论】:

如何最小化标签小部件右上角的内边距和边距?我希望按钮粘在表单的顶部,所以当我将鼠标悬停在右上角时,我可以点击“X”按钮 @ĐứcHảiTrần 根据我的测试,按钮已经放置在选项卡小部件的右上角,但在某些系统中,默认按钮大小提示可能小于选项卡栏。尝试将每个按钮的 minimumHeight 设置为self.tabWidget.tabBar().sizeHint().height()。这可能会使其与标签栏底部重叠,如果是这种情况,请从 sizeHint 高度中减去 self.style().pixelMetric(QtWidgets.QStyle.PM_TabBarBaseHeight, None, None) 的结果。 我想删除填充(图片链接中的红色箭头)image。我已经尝试设置 minimizeHeight 但没有效果。 这些是按钮的绘图边距,它们完全取决于样式。事实上,即使鼠标不在按钮的可视边界内,您仍然可以单击它们,它们会做出相应的反应。虽然您可以通过考虑这些边距来手动移动小部件,但实际上无法知道 visual 填充的大小,因为绘图是使用内部计算完成的,并且经常使用像素图。即使您通过反复试验找到了一种方法,也不能保证它在其他计算机上看起来也一样。 唯一的选择是setStyleSheet()为每个按钮(包括所有可能的伪状态)具有不同的边框样式(通常是insetoutset),或者通过继承QPushButton自己绘制它们(或 QToolButton)并覆盖他们的 paintEvent 方法,但这显然会破坏与系统的视觉一致性。

以上是关于Qt Designer 使小部件在布局中与另一个小部件重叠的主要内容,如果未能解决你的问题,请参考以下文章

第15.13节 PyQt(Python+Qt)入门学习:Qt Designer的Spacers部件详解

如何在 Qt-Designer 中使用自定义小部件

Qt Designer常用部件介绍

是否可以在 Qt Designer 中使用来自 Qt Designer 的 .ui 文件作为自定义小部件?

如何在 PyQt 中为 Qt-Designer 小部件实现 MousePressEvent

使用 Python 为 Qt Designer 自定义 Qt 小部件