1

Is there a way to make a resizable QMessageBox in PyQt? How can I do this?

If I write this code:

mbox = QMessageBox()
mbox.setText('tesdt')
mbox.setTitle('test')
mbox.exec()

The messagebox cannot be resized. How can I make it resizable?

Ryan Glenn
  • 1,325
  • 4
  • 17
  • 30
  • Can you please explain what you mean by "resizable"? User interaction? Programmatical geometry setting? What OS are you on? Please, add more details to your questions. – musicamante Jun 02 '22 at 02:26
  • I want to be able to click the edges of the messagebox and resize it like I can do with any other application (firefox, chrome, etc). Does that make sense? – Ryan Glenn Jun 02 '22 at 02:55
  • See [this answer](https://stackoverflow.com/a/72478265/2001654). – musicamante Jun 02 '22 at 14:58

1 Answers1

-1

You can create an inherited class from QMessageBox() and modify it to be resizable like I do in this code:

import sys
from PyQt5.QtWidgets import (
    QApplication,
    QPushButton,
    QWidget,
    QMessageBox,
    QVBoxLayout,
    QTextEdit,
    QSizePolicy
)

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

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

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

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

        return result

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QGridLayout Example")

        self.button = QPushButton("Show message")
        self.layout2 = QVBoxLayout()

        self.layout2.addWidget(self.button)
        self.setLayout(self.layout2)
        self.button.clicked.connect(self.show_message)
        
    def show_message(self):
        self.mbox = MyMessageBox()
        self.mbox.setIcon(MyMessageBox.Information)
        self.mbox.setStandardButtons(MyMessageBox.Ok)
        self.mbox.setText('test')
        self.mbox.setWindowTitle('test')
        self.mbox.show()
        
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

enter image description here

OualidSai
  • 97
  • 1
  • 5
  • First of all, that code is almost the exact copy of [this post](https://stackoverflow.com/a/2664019). Then, while it "works", it's a *bad* solution: 1. `event()` is called *extremely* often, for dozens of event types that have absolutely nothing to do with the size; 2. setting size constraints *within* an event handler must be done with extreme care; 3. setting a size policy for a top level widget is completely useless, since it's used by the layout of the parent. – musicamante Jun 02 '22 at 14:30
  • Hi @musicamante, please give me at least one reference for your claims! – OualidSai Jun 02 '22 at 14:56
  • Try to add a `print(e)` in `event()` and you'll see the amount of calls for that override, and, so, the amount of *unnecessary* calls done afterwards: what would be the point to call those functions on a focus change or paint event? Also, as the [documentation explains](//doc.qt.io/qt-5/qsizepolicy.html#details): "The size policy of a widget [...] affects how the widget is treated by the layout engine.". So, setting a generic, expanding size policy is completely useless for top level widgets, remove it and you'll see that it won't change absolutely *anything*. – musicamante Jun 02 '22 at 15:06
  • @musicamante, in your provided ref from Qt docs, in the "Detailed Description" section, "The size policy of a widget" is an expression of "its" willingness to be resized in various ways, and affects how the widget is treated by the layout engine. Each widget returns a QSizePolicy that describes the horizontal and vertical resizing policy "it" prefers when being laid out. You can change this for a "specific widget" by changing "its" QWidget::sizePolicy property. (focus on double quotations). – OualidSai Jun 02 '22 at 15:14
  • Exactly, *when being laid out*, which is, "when a parent layout manager lays the widget out". The only occasion in which the size policy is considered on a top level widget is when `adjustSize()` is called (implicitly or explicitly), and that widget has *no* layout manager set; in that case (which is *not* this, since a layout exists) it will consider the expanding directions of the policy to know if it can be resized based on its size hint and/or using the `heightForWidth()`. Again, try to remove `setSizePolicy()`, and you will see that it will change absolutely *nothing*. – musicamante Jun 02 '22 at 15:32