用PyQt4调整对话框大小
我有一段代码:
import sys
from PyQt4.QtGui import (QApplication, QHBoxLayout, QVBoxLayout, QDialog,
QFrame, QPushButton, QComboBox)
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
moreButton = QPushButton('moreButton')
moreButton.setCheckable(True)
resizeButton = QPushButton('Resize')
combo = QComboBox()
combo.addItems(['item1', 'item2'])
layout1 = QHBoxLayout()
layout1.addWidget(moreButton)
layout1.addWidget(resizeButton)
layout2 = QHBoxLayout()
layout2.addWidget(combo)
self.frame = QFrame()
self.frame.setLayout(layout2)
self.frame.hide()
layout3 = QVBoxLayout()
layout3.addLayout(layout1)
layout3.addWidget(self.frame)
moreButton.toggled.connect(self.frame.setVisible)
moreButton.clicked.connect(self.method)
resizeButton.clicked.connect(self.method)
self.setLayout(layout3)
self.resize(630, 50)
def method(self):
if self.frame.isVisible():
self.resize(630, 150)
else:
self.resize(630, 250)
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
我运行这段代码,当点击moreButton时,ComboBox会出现或消失。对话框的大小也会随之变化。但是,如果我把方法改成:
def method(self):
if self.frame.isVisible():
self.resize(630, 150)
else:
self.resize(630, 50)
(这样可以在ComboBox隐藏时设置初始大小)调整大小就不管用了。不过,如果我点击resizeButton——这个按钮连接的是同一个方法——调整大小就能正常工作。
我知道还有其他方法可以达到这个效果(比如使用layout.setSizeConstraint(QLayout.SetFixedSize)),但我想明确地声明大小。
我哪里做错了?
4 个回答
这个问题似乎是因为事件处理的顺序出了问题。
这里有一个简单的解决办法:
def method(self):
app.processEvents()
if self.frame.isVisible():
self.resize(630, 150)
else:
self.resize(630, 50)
这个问题和答案对我来说很有帮助:我想让一个QDialog的大小自动适应里面的内容,这个内容是一个QLabel,内容的大小是变化的。同时,我还想避免在QDialog的边框出现双箭头光标。虽然我把对话框的大小设置成了固定的,但双箭头还是会出现,尽管它是不能被调整大小的(根本不会动)。而且,虽然里面的布局确实会自动调整大小,但如果我在布局上使用SetFixedSize(真是意外),那么那些烦人的双箭头就消失了。
QDialog: QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
QLayout: setSizeConstraint(QLayout.SetFixedSize)
QLabel: QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
...现在这个对话框的大小能够适当地根据标签里的内容来调整,但对话框本身看起来是不能被用户调整大小的,这对显示信息和错误消息来说是好的。
这让我觉得有点反直觉,所以我觉得值得在这里分享给其他人。
再多说一点...
self.label = QtGui.QLabel(self)
self.label.sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
self.label.setSizePolicy(self.label.sizePolicy)
self.label.setMinimumSize(QtCore.QSize(450, 40))
self.label.setWordWrap(True)
self.verticalLayout = QtGui.QVBoxLayout(self)
# get rid of overall dialog resize arrows
self.verticalLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize) # no resize arrows
self.verticalLayout.addWidget(self.label)
我猜你的问题是,你在隐藏一些东西之后,试图调整 QDialog
的大小,但它还没来得及重新调整大小。也就是说,当你调用 resize
的时候,它的 minimumSize
还在确保按钮和下拉框是可见的。等你过了一段时间再调用,它的 minimumSize
就调整好了,这样就能正常响应了。
一个简单的解决办法是在调整大小之前手动设置 minimumSize
:
def method(self):
if self.frame.isVisible():
# uncomment below, if you like symmetry :)
# self.setMinimumSize(630, 150)
self.resize(630, 150)
else:
self.setMinimumSize(630, 50)
self.resize(630, 50)
不过,如果是我来处理这个问题,我会把调整大小的管理交给布局,并使用 sizeConstraint
。反正这些布局就是为了这个目的的。