`QMenu.setTearOffEnabled`窗口无法正确调整自身大小以显示`QtWidgets.QWidgetAction`

问题描述 投票:0回答:1

QMenu
正确显示包含具有自己尺寸的
QWidgetAction
QWidget
,但是当菜单被撕下(并成为独立窗口)时,事情就会出错。窗口大小可正确显示使用
addAction(str)
添加的任何操作,但
QWidgetAction
QWidget
几乎完全隐藏。

此代码重现了问题:

#!/usr/bin/env python

from PySide2 import QtCore, QtWidgets


def main():
    app = QtWidgets.QApplication()
    window = QtWidgets.QWidget()
    layout = QtWidgets.QHBoxLayout()
    window.setLayout(layout)
    button = QtWidgets.QPushButton("Push Me")

    menu = QtWidgets.QMenu()
    menu.setTearOffEnabled(True)
    menu.addAction("Ok")

    qwa = QtWidgets.QWidgetAction(menu)
    big_button = QtWidgets.QPushButton("Big Button")
    big_button.setMinimumWidth(400)
    big_button.setMinimumHeight(400)
    qwa.setDefaultWidget(big_button)

    menu.addAction(qwa)
    button.setMenu(menu)
    layout.addWidget(button)
    window.show()
    app.exec_()

main()

python pyqt5 pyside2 qwidgetaction
1个回答
0
投票

这是因为当 QMenu 被撕下时,您实际上看不到相同 QMenu 对象,而是基于它的new QMenu。

QMenu 文档实际上解释了这一点,但我承认可以更加强调这个重要方面:

QMenu 还可以提供可撕式菜单。撕式菜单是一个顶级窗口,其中包含菜单的副本

然后,请注意QWidgetAction 描述中的这一部分

如果您只有一个自定义小部件,那么您可以使用 setDefaultWidget() 将其设置为默认小部件。如果该操作被添加到 QToolBar,或者通常添加到支持 QWidgetAction 的操作容器,则将使用该小部件。如果仅具有默认小部件的 QWidgetAction 同时添加到两个工具栏,则默认小部件将显示仅在第一个工具栏中添加了操作。

上述内容不仅对工具栏有效,而且对菜单(“支持 QWidgetAction 的操作容器”)有效,包括 tear off 菜单:如果您将相同的 QWidgetAction 添加到多个菜单,并且该操作仅实现

 setDefaultWidget()
,小部件仅在第一个菜单中可见,这正是使用撕下时发生的情况。

解决方案是继承 QWidgetAction 并使用

createWidget()
代替:

class ButtonAction(QtWidgets.QWidgetAction):
    def createWidget(self, parent):
        big_button = QtWidgets.QPushButton("Big Button", parent)
        big_button.setMinimumWidth(400)
        big_button.setMinimumHeight(400)
        return big_button


...
menu = QtWidgets.QMenu()
qwa = ButtonAction(menu)
menu.addAction(qwa)

请注意,您可能应该将按钮的

clicked
信号连接到操作的
triggered
信号。

© www.soinside.com 2019 - 2024. All rights reserved.