Как разрешить изменение размера QMessageBox в PyQt4

Я использую приятную функцию в QMessageBox, чтобы дополнительно показывать пользователю подробный текст. Однако окно после расширения все еще довольно маленькое, и сразу же пытаются изменить размер окна, чтобы было видно больше деталей. Даже после установки правильных, на мой взгляд, настроек размер не изменится.

Вот соответствующий фрагмент кода PyQt4:

mb = QMessageBox()
mb.setText("Results written to '%s'" % filename)
mb.setDetailedText(str(myData))
mb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
mb.setSizeGripEnabled(True)

Я пропустил шаг и/или это вообще возможно?


person metasim    schedule 16.04.2010    source источник
comment
Вы имеете в виду, что когда отображается QMessageBox, он недостаточно велик для отображения вашего контента (например, что-то обрезается)?   -  person Brian Roach    schedule 16.04.2010
comment
Извините, я не был ясен. Я имел в виду, что подробный текст ограничен небольшой текстовой областью (с полосами прокрутки). Просматриваемый, но не приятный с точки зрения пользователя. Если бы размер QMessageBox можно было просто изменить вручную по желанию пользователя, это значительно улучшило бы общий опыт. Даже с вызовами setSizePolicy() и setSizeGripEnabled() по-прежнему невозможно изменить размер окна.   -  person metasim    schedule 16.04.2010
comment
Вы пробовали политику размера MinimumExpanding? Кроме того, проверьте, какой максимальный размер установлен. Возможно, вам придется создать подкласс QMessageBox и повторно реализовать sizeHint(), чтобы вернуть то, что вы хотите. Я всегда обнаруживал, что есть немного вуду, связанного с тем, чтобы заставить виджеты верхнего уровня изменять свой размер соответствующим образом в зависимости от их содержимого. Еще одна вещь, которую вы можете попробовать, это установить ограничение размера макета: mb.layout()->setSizeConstraint(QLayout::SetMaximumSize) (А, это С++ - не знаком с синтаксисом python)   -  person Brian Roach    schedule 17.04.2010


Ответы (3)


Это решение, которое я бы использовал. Это не делает размер диалогового окна изменяемым, но позволяет диалоговому окну изменяться до разумного размера, когда поле сведений отображается. Я беззастенчиво украл некоторые идеи из ответа serge_gubenko. Даже если вы предпочитаете реализовать его изменение размера, я скромно предлагаю некоторые другие улучшения ниже.

# Safe since everything in the namespace begins with 'Q'
from PyQt4.QtGui import *

class MyMessageBox(QMessageBox):

    # This is a much better way to extend __init__
    def __init__(self, *args, **kwargs):            
        super(MyMessageBox, self).__init__(*args, **kwargs)
        # Anything else you want goes below

    # We only need to extend resizeEvent, not every event.
    def resizeEvent(self, event):

        result = super(MyMessageBox, self).resizeEvent(event)

        details_box = self.findChild(QTextEdit)
        # 'is not' is better style than '!=' for None
        if details_box is not None:
            details_box.setFixedSize(details_box.sizeHint())

        return result
person Paul Etherton    schedule 02.04.2012
comment
В линуксе это вообще не работает. Но даже если бы это сработало, это не дало бы ответа на вопрос, потому что это не позволяет изменять размер окна сообщения. (PS: переопределение __init__ в этом примере совершенно избыточно). - person ekhumoro; 04.11.2017

если вы хотите создать окно сообщения с изменяемым размером, пожалуйста, проверьте, подойдет ли вам приведенный ниже код:

class MyMessageBox(QtGui.QMessageBox):
    def __init__(self):
        QtGui.QMessageBox.__init__(self)
        self.setSizeGripEnabled(True)

    def event(self, e):
        result = QtGui.QMessageBox.event(self, e)

        self.setMinimumHeight(0)
        self.setMaximumHeight(16777215)
        self.setMinimumWidth(0)
        self.setMaximumWidth(16777215)
        self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)

        textEdit = self.findChild(QtGui.QTextEdit)
        if textEdit != None :
            textEdit.setMinimumHeight(0)
            textEdit.setMaximumHeight(16777215)
            textEdit.setMinimumWidth(0)
            textEdit.setMaximumWidth(16777215)
            textEdit.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)

        return result

вот как называется окно сообщений:

mb = MyMessageBox()
mb.setText("Results written to '%s'" % 'some_file_name')
mb.setDetailedText('some text')
mb.exec_()

решение взято из здесь

надеюсь, это поможет, с уважением

person serge_gubenko    schedule 18.04.2010
comment
Это определенно на правильном пути (жаль, что это нужно делать в обработчике событий). Размер диалогового окна теперь изменяется, но все изменения размера относятся к метке вверху, а не к текстовому полю. Я потратил около получаса, играя с настройкой sizePolicy других компонентов и rowStretch базового макета, но дальше так и не продвинулся. Это определенно лучше, чем то, что у меня было. Я опубликую продолжение, если выясню, как выделить все дополнительное вертикальное пространство для текстовой области. - person metasim; 19.04.2010
comment
@serge_gubenko, когда я нажимаю кнопку максимизации в диалоговом окне (это отображается при нажатии кнопки «Показать подробности»), диалоговое окно на мгновение максимизируется, а затем сразу же возвращается в нормальное состояние (и перемещается в верхний левый угол экрана). ). Любая идея, как можно исправить работу кнопки максимизации? - person Pushpak Dagade; 10.07.2013
comment
Кажется, это лучшее решение на данный момент. Однако при каждом нажатии кнопки «Показать детали/Скрыть детали» размер меняется до исходного небольшого размера. Кажется, внутри QMessageBox есть метод updateSize(), который вычисляет размер, но перезапись его не имеет никакого значения, по крайней мере, в PyQt. - person Jason; 05.03.2019
comment
Я попытался распечатать все типы событий, пока я перетаскиваю и изменяю размер с помощью рукоятки. Он прекрасно работает, комментируя несколько событий, и в итоге у меня осталось только одно: QEvent::CursorChange для обработки. - person ZHANG Zikai; 03.05.2021

Это работает, но проверено только в Linux под Gnome 2. Он изменяет размер по горизонтали, только если не включен текст «показать подробности», и в этом случае он изменяется в обоих направлениях. Кнопка "показать подробности" по-прежнему сбрасывает его до исходного размера, это либо фича, либо баг, в зависимости от вашего pov:

bool MyMessageBox::event(QEvent* e)
{
    bool result = QMessageBox::event(e);
    // force resizing back on, QMessageBox keeps turning it off:
    if (maximumWidth() != QWIDGETSIZE_MAX) {
        QTextEdit *textEdit = findChild<QTextEdit*>();
        if (textEdit && textEdit->isVisible()) {
            textEdit->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
            textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
            setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
            setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        } else {
            setMaximumWidth(QWIDGETSIZE_MAX);
            setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        }
    }
    return result;
}
person user3080602    schedule 07.04.2016