使用PyQt4调整对话框的大小

时间:2011-12-22 18:59:37

标签: python qt pyqt 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出现或消失。 Dialog的大小也会发生变化。但是,如果我将方法更改为:

def method(self):
    if self.frame.isVisible():           
        self.resize(630, 150)
    else:
        self.resize(630, 50)

(为了在隐藏组合时设置初始大小),调整大小不起作用。但是,如果我单击resizeButton - 它连接到相同的方法 - 调整大小正常工作。

我知道还有其他方法可以实现这样的结果(例如layout.setSizeConstraint(QLayout.SetFixedSize)),但我想明确声明大小。

我做错了什么?

4 个答案:

答案 0 :(得分:6)

我的猜测是,在你隐藏东西之后,你有时间重新调整它的大小之前,你试图调整QDialog的大小。因此,在调用resize时,它有一个minimumSize,可确保按钮和组合框可见。在一段时间后调用它时,它现在具有正确的miminumSize并正确响应。

快速修复是在调整大小之前手动覆盖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。无论如何,这就是这些布局。

答案 1 :(得分:3)

这个问题和答案在我的情况下很有帮助:使用QLayout / QVBoxLayout自动调整QDialog,其中包含可变大小内容/消息的QLabel,同时还避免在整个QDialog容器的边框处使用双箭头光标。对话框本身的sizePolicy设置为Fixed,但即使无法调整大小(不会让步),箭头也会出现。即使内部布局 自动/神奇地调整大小,在布局上使用SetFixedSize(惊喜,惊喜)使整个QDialog的那些恼人的双箭头消失了。

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)

答案 2 :(得分:2)

此问题似乎是由处理事件的顺序引起的。

这是一个简单的解决方法:

def method(self):
    app.processEvents()
    if self.frame.isVisible():           
        self.resize(630, 150)
    else:
        self.resize(630, 50)

答案 3 :(得分:1)

你试过这个吗?除非我误解,否则这就是你想做的事。

def method(self):
    if self.frame.isVisible():   
        self.resize(630, 150)
        self.frame.setVisible(False)
    else:
        self.resize(630, 50)

编辑:最终答案是 layout3.setSizeConstraint(QLayout.SetNoConstraint)