PyQt - 手动调整菜单小部件的大小不会调整其内容的大小 [英] PyQt - Manually resizing menu widget does not resize its content

查看:66
本文介绍了PyQt - 手动调整菜单小部件的大小不会调整其内容的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 QToolButton 打开一个菜单,这是一个简单的 QWidget.在这个小部件内有一个 QTextEdit 和一个按钮.在右下角有一个 QSizeGrip,我想用它来让用户调整小部件的大小,从而调整 QTextEdit.

I am using a QToolButton to open up a menu, which is a simple QWidget. Inside this widget live a QTextEdit and a Button. At the lower right corner there is a QSizeGrip which I want to use to let the user resize the widget and thus the QTextEdit.

如果我在 MainWindow (Option1) 中单独使用这个小部件,一切都会按预期进行.但是,如果我将此小部件放入菜单 (Option2),则无法再调整它的大小.拖动 QSizeGrip 会更改 Menu 的大小,但不会更改 Widget 的大小.我已经尝试过 setWindowFlags(QtCore.Qt.SubWindow)setSizePolicy(..) 没有任何显着效果.

If I use this widget on its own inside a MainWindow (Option1) everything works as expected. If however I put this widget into the menu (Option2), I cannot resize it anymore. Dragging the QSizeGrip changes the size of the Menu but not the Widget. I have already experimented with setWindowFlags(QtCore.Qt.SubWindow) and setSizePolicy(..) without any notable effect.

我的问题是:如何使小部件(与 TextEdit 一起)可调整大小?

My Question is: How do I make the widget (together with the TextEdit) resizable?

这是代码和下面的图片.

Here is the code and below a picture.

import sys
from PyQt4 import QtGui, QtCore

class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)

        self.setLayout(QtGui.QVBoxLayout())
        self.TextEdit = QtGui.QTextEdit()

        self.Button = QtGui.QPushButton("Push")

        self.UpdateWidget = QtGui.QWidget()
        self.UpdateWidget.setLayout(QtGui.QHBoxLayout())
        self.UpdateWidget.layout().addWidget(self.Button, 1)
        self.UpdateWidget.layout().addWidget(QtGui.QSizeGrip(self), 0)

        self.layout().addWidget(self.TextEdit)
        self.layout().addWidget(self.UpdateWidget)

        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0,0,0,0)
        self.UpdateWidget.layout().setSpacing(4)
        self.UpdateWidget.layout().setContentsMargins(0,0,0,0)

        # This is what I already tried to make the menu resizable:
        #self.setWindowFlags(QtCore.Qt.SubWindow)
        #self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        #self.TextEdit.setWindowFlags(QtCore.Qt.SubWindow)
        #self.TextEdit.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)


class ToolBar(QtGui.QWidget):
    def __init__(self, parent=None):
        super(ToolBar, self).__init__(parent)
        self.setLayout(QtGui.QHBoxLayout())
        self.Button = QtGui.QToolButton()
        self.Button.setText("Open Text Editor")
        self.Button.setPopupMode(QtGui.QToolButton.InstantPopup)
        self.Button.setMenu(QtGui.QMenu(self.Button))
        action = QtGui.QWidgetAction(self.Button)
        action.setDefaultWidget(MyWidget())
        self.Button.menu().addAction(action)
        self.layout().addWidget(self.Button)


class App(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        #Option 1: 
        #Use MyWidget in MainWindow. This works as expected.
        #self.central = MyWidget()

        #Option 2:
        #Use MyWidget as default widgt for a menu action. 
        #In this case MyWidget cannot be resized.
        self.central = ToolBar()

        self.setCentralWidget(self.central)


if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    thisapp = App()
    thisapp.show()
    sys.exit(app.exec_())

推荐答案

问题是因为 Button.menu 没有通知您的小部件有关大小更改的信息.

Problem is because Button.menu doesn't inform your widget about size change.

在工具栏中,您可以将自己的函数分配给 resizeEvent,这将调整您的小部件的大小.

In ToolBar you can assign own function to resizeEvent which will resize your widget.

您需要访问您的小部件

    self.MyW = MyWidget()

并且您可以分配自己的功能

and you can assign own function

    self.Button.menu().resizeEvent = self.onResize

def onResize(self, event):        
    self.MyW.resize(event.size())

完整代码:

import sys
from PyQt4 import QtGui, QtCore

class MyWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)    
        self.setLayout(QtGui.QVBoxLayout())

        self.TextEdit = QtGui.QTextEdit()

        self.Button = QtGui.QPushButton("Push")

        self.UpdateWidget = QtGui.QWidget()
        self.UpdateWidget.setLayout(QtGui.QHBoxLayout())
        self.UpdateWidget.layout().addWidget(self.Button, 1)
        self.UpdateWidget.layout().addWidget(QtGui.QSizeGrip(self), 0)

        self.layout().addWidget(self.TextEdit)
        self.layout().addWidget(self.UpdateWidget)

        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0,0,0,0)
        self.UpdateWidget.layout().setSpacing(4)
        self.UpdateWidget.layout().setContentsMargins(0,0,0,0)


class ToolBar(QtGui.QWidget):

    def __init__(self, parent=None):
        super(ToolBar, self).__init__(parent)
        self.setLayout(QtGui.QHBoxLayout())

        self.Button = QtGui.QToolButton()
        self.Button.setText("Open Text Editor")
        self.Button.setPopupMode(QtGui.QToolButton.InstantPopup)
        self.Button.setMenu(QtGui.QMenu(self.Button))

        self.MyW = MyWidget() # <-- here
        action = QtGui.QWidgetAction(self.Button) 
        action.setDefaultWidget(self.MyW) # <-- here

        self.Button.menu().addAction(action)
        self.layout().addWidget(self.Button)

        self.Button.menu().resizeEvent = self.onResize # <-- here

    def onResize(self, event):        # <-- here
        self.MyW.resize(event.size()) # <-- here

class App(QtGui.QMainWindow):

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

        #Option 1: 
        #Use MyWidget in MainWindow. This works as expected.
        #self.central = MyWidget()

        #Option 2:
        #Use MyWidget as default widgt for a menu action. 
        #In this case MyWidget cannot be resized.
        self.central = ToolBar()

        self.setCentralWidget(self.central)


if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    thisapp = App()
    thisapp.show()
    sys.exit(app.exec_())

<小时>

也许它可以用 SizeGripMyWidget 来完成,但我没有尝试


Maybe it can be done olny with SizeGrip and MyWidget but I didn't try

这篇关于PyQt - 手动调整菜单小部件的大小不会调整其内容的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆