PyQt - 手动调整菜单小部件的大小不会调整其内容的大小
Posted
技术标签:
【中文标题】PyQt - 手动调整菜单小部件的大小不会调整其内容的大小【英文标题】:PyQt - Manually resizing menu widget does not resize its content 【发布时间】:2016-10-19 16:12:48 【问题描述】:我正在使用 QToolButton 打开一个菜单,这是一个简单的 QWidget。在这个小部件内有一个 QTextEdit 和一个按钮。在右下角有一个 QSizeGrip,我想用它来让用户调整小部件的大小,从而调整 QTextEdit。
如果我在 MainWindow (Option1) 中单独使用这个小部件,一切都会按预期工作。但是,如果我将此小部件放入菜单 (Option2),我将无法再调整它的大小。拖动 QSizeGrip 会更改 Menu 的大小,但不会更改 Widget。我已经尝试过setWindowFlags(QtCore.Qt.SubWindow)
和setSizePolicy(..)
没有任何明显的效果。
我的问题是:如何使小部件(连同 TextEdit)可调整大小?
这是代码,下面是一张图片。
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_())
【问题讨论】:
【参考方案1】:问题是因为Button.menu
没有通知您的小部件尺寸变化。
在工具栏中,您可以将自己的函数分配给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_())
也许可以用SizeGrip
和MyWidget
完成,但我没有尝试
【讨论】:
以上是关于PyQt - 手动调整菜单小部件的大小不会调整其内容的大小的主要内容,如果未能解决你的问题,请参考以下文章