Disable a QDialogButtonBox button In a custom PySide6 QDialog

44 views Asked by At

My intent is to provide a dialog where the user can enter and return a name value (or an empty string if the dialog is cancelled).

I have a custom dialog which has a QDialogButtonBox and a QLineEdit.The button box has OK and Cancel buttons. I would like to disable the OK button when the QLineEdit has an empty string.

This is my first posting, so please pardon me if there's an obvious solution

Here's part of my dialog:

class TableNameDialog(QDialog, Ui_TableNameDialog):
    
    ...

    def exec(self):
        execResult = super().exec()
        if not execResult:
            return ""
        
        txt = self.tableNameLe.text()
        if len(txt) > 0:
            return txt
        else:
            return ""

And here's part of the dialog's UI in Qt Designer:

class Ui_TableNameDialog(object):
    def setupUi(self, TableNameDialog):

        ...
        self.tableNameLe = QLineEdit(TableNameDialog)
        self.tableNameLe.setObjectName(u"tableNameLe")

        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.tableNameLe)

        ...
        self.buttonBox = QDialogButtonBox(TableNameDialog)
        self.buttonBox.setObjectName(u"buttonBox")
        self.buttonBox.setEnabled(True)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)

I'm darned if I know how to disable/enable the QDialogBox's OK button.

I've searched the QDialogButtonBox PySide6 docs but couldn't find anything pertinent.

1

There are 1 answers

9
musicamante On BEST ANSWER

Standard QDialogButtonBox buttons are accessible using the button() function along with their StandardButton enum.

You can therefore disable the Ok button depending on the contents of the line edit:

class TableNameDialog(QDialog, Ui_TableNameDialog):

    ...

    def validate(self):
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
            bool(self.tableNameLe.text())
        )


    def exec(self):
        self.validate()
        self.tableNameLe.textEdited.connect(self.validate)

        if super().exec():
            return self.tableNameLe.text()
        return ''

Notes:

  • you may want to actually validate the contents of the line edit; the simplest way is to use str.strip() in validate(), so that it will be considered acceptable as long as any non-space character has been entered;
  • if you're going to return a string anyway, there's really no point in checking if the string length is greater than 0: if the string is empty, it would be "" anyway (return txt if len(txt) > 0 else "" is exactly the same as return txt);
  • if you plan to reuse the same instance, you should disconnect the textEdited signal before returning, otherwise it will be called as many times as exec() has been called on the same instance; alternatively use a try/except block that attempts to connect the signal with the Qt.UniqueConnection argument, or just connect it within the __init__ of the class;