pythonpyqtpyqt5qinputdialog

PyQt5 - resize (limit maximum size) input dialog


I read this: How to resize QInputDialog, PyQt but it didnt work for me, as it seems to be about PyQt4

This is my code snipplet:

    def ImportURL(self):                     #URL dialog aufrufen
        InputDialog = QtWidgets.QInputDialog(self)
        i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")

        if okPressed:
            self.getWebsite(i)

And i tried adding .setFixedSize in the 2nd line. I tried adding InputDialog.setFixedSite(self) between line 2 and 3. Nothing worked, it either crashes or it creates a second, empty window. Am i overlooking something here?


Solution

  • In the answers to the other question do not explain the cause of the problem so in my answer will try to cover as much as possible

    Explanation:

    The getText() method is a static method, which means that an object is not used, in the method internally if it is used but it is not accessible. So the InputDialog that you create is not the one you show and this you can check using the following code since you will see 2 windows:

    def ImportURL(self):
        InputDialog = QtWidgets.QInputDialog(self)
        InputDialog.show()
        i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
    
        if okPressed:
            self.getWebsite(i)
    

    Solutions:

    So there are the following solutions:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            button = QtWidgets.QPushButton(
                "Open QInputDialog", clicked=self.ImportURL
            )
            vlay = QtWidgets.QVBoxLayout(self)
            vlay.addWidget(button)
    
        @QtCore.pyqtSlot()
        def ImportURL(self):
            QtCore.QTimer.singleShot(0, self.after_show)
            i, okPressed = QtWidgets.QInputDialog.getText(
                self,
                "Import website",
                "Site to import:",
                QtWidgets.QLineEdit.Normal,
                "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite",
            )
            if okPressed:
                # self.getWebsite(i)
                print(i)
    
        @QtCore.pyqtSlot()
        def after_show(self):
            size = QtCore.QSize(500, 100)
            for d in self.findChildren(QtWidgets.QInputDialog):
                if d.isVisible():
                    d.resize(size)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    
    1. Do not use the getText() method but create an object that implements the same logic:
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Widget, self).__init__(parent)
            button = QtWidgets.QPushButton(
                "Open QInputDialog", clicked=self.ImportURL
            )
            vlay = QtWidgets.QVBoxLayout(self)
            vlay.addWidget(button)
    
        @QtCore.pyqtSlot()
        def ImportURL(self):
            dialog = QtWidgets.QInputDialog(self)
            dialog.resize(QtCore.QSize(500, 100))
            dialog.setWindowTitle("Import website")
            dialog.setLabelText("Site to Import")
            dialog.setTextValue(
                "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
            )
            dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
            if dialog.exec_() == QtWidgets.QDialog.Accepted:
                i = dialog.textValue()
                print(i)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())
    

    Update:

    The layout of the QInputDialog has QLayout::SetMinAndMaxSize set as sizeConstraint, so the fixed size will not work, the trick is to change it to QLayout::SetDefaultConstraint:

    from functools import partial
    
    # ...
    
    @QtCore.pyqtSlot()
    def ImportURL(self):
        dialog = QtWidgets.QInputDialog(self)
        dialog.setWindowTitle("Import website")
        dialog.setLabelText("Site to Import")
        dialog.setTextValue(
            "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
        )
        dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
        wrapper = partial(self.on_timeout, dialog)
        QtCore.QTimer.singleShot(0, wrapper)
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            i = dialog.textValue()
            print(i)
    
    def on_timeout(self, dialog):
        lay = dialog.layout()
        lay.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        dialog.setFixedSize(QtCore.QSize(500, 100))