PyQt - Manual Resize Menu Widget Does Not Resize Content

I use QToolButton to open a menu, which is a simple QWidget. Inside this widget is a QTextEdit and a button. In the lower right corner is QSizeGrip, which I want to use to allow the user to resize the widget and therefore QTextEdit.

If I use this widget myself inside MainWindow (Option1), everything works as expected. If, however, I put this widget in the menu (Option2), I can no longer change it. Dragging and dropping QSizeGrip resizes the menu, but not the widget. I have already experimented with setWindowFlags(QtCore.Qt.SubWindow)and setSizePolicy(..)without any noticeable effect.

My question is: How to change the widget (along with TextEdit)?

Here is the code below the 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_())

enter image description here

0
1

, Button.menu .

ToolBar resizeEvent, .

    self.MyW = MyWidget()

    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_())

, olny SizeGrip MyWidget,

+1

Source: https://habr.com/ru/post/1660413/


All Articles