изменение размера диалога с PyQt4 - PullRequest
9 голосов
/ 22 декабря 2011

У меня есть этот пример кода:

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)

(чтобы установить начальный размер, когда комбо скрыт), изменение размера не будет работать.Однако, если я нажимаю кнопку resizeButton, которая подключена к тому же методу, изменение размера работает правильно.

Я знаю, что есть другие способы достижения такого результата (например, layout.setSizeConstraint (QLayout.SetFixedSize)), но я хочу объявить размер явно.

Что я делаю не так?

Ответы [ 4 ]

6 голосов
/ 23 декабря 2011

Я предполагаю, что вы пытаетесь изменить размер 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.Это то, что эти макеты для в любом случае.

3 голосов
/ 10 мая 2012

Этот вопрос и ответы были полезны в моей ситуации: автоматическое определение размера QDialog с помощью QLayout / QVBoxLayout, содержащего 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 голосов
/ 23 декабря 2011

Эта проблема вызвана порядком, в котором обрабатываются события.

Вот простое исправление:

def method(self):
    app.processEvents()
    if self.frame.isVisible():           
        self.resize(630, 150)
    else:
        self.resize(630, 50)
1 голос
/ 22 декабря 2011

ты пробовал это?если я не пойму неправильно, это то, что вы хотите сделать.

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

edit: окончательный ответ layout3.setSizeConstraint (QLayout.SetNoConstraint)

...