pythonpysideqcomboboxqdirqvalidator

Validate if editable QCombobox input is a directory via QValidator


I try to validate if a editable QCombobox input is a directory or not before it gets added to the QCombobox.

from PySide import QtGui, QtCore

class DirValidator(QtGui.QValidator):
    def __init__(self, cb_input):
        super(DirValidator, self).__init__()
        self._input = cb_input

    def validate(self, _text, _pos):
        _dir = QtCore.QDir(_text)
        if self._input.hasFocus():  # ignore validation while editing not complete
            return QtGui.QValidator.Acceptable
        if QtCore.QDir.exists(_dir):
            return QtGui.QValidator.Acceptable
        return QtGui.QValidator.Invalid


dir_validator = DirValidator(self.cb_path.lineEdit())
self.cb_path.setValidator(dir_validator)

sadly it does not work properly because every input still gets added to the combobox when i hit enter. Any suggestions?

EDIT: i also tried to use the validator on the QLineEdit like so:

dir_validator = DirValidator(self.cb_path.lineEdit())
self.cb_path.lineEdit().setValidator(dir_validator)

Does not work either.

EDIT: It kinda works...but when i press return "hasFocus" is still True so it is just accepting the input and then of course adding it to the combobox. if i get rid of "if self._input.hasFocus():" it does not accept any input if i type it in...just if a paste a complete directory path. So what i need is a way to check if the edit is finished to then check if it is a directory. And as far as i understand i can only check this in a combobox via QValidator...because it adds the input to the box right away...before i can intercept it in any way.

EDIT: i did find solution for my case. I just abandoned the whole validator approach. The purpose of that was to prevent the combobox from creating a new item if it was no valid directory...what i now did instead was to validate the input after it was finished by taking advantage of the QLineEdit().editingFinished() signal. After it created the new Item i just removed it again if the input was not valid and it also gave me the opportunity to add a error Popup telling the user that the input was no directory.


Solution

  • I do not see the need for hasFocus(), because if you are writing to the QLineEdit it obviously has the focus. If the path is incorrect then you must return a QValidator::Intermediate:

    from PySide import QtGui, QtCore
    
    class DirValidator(QtGui.QValidator):
        def validate(self, _text, _pos):
            _dir = QtCore.QDir(_text)
            if _dir.exists():
                return QtGui.QValidator.Acceptable
            return QtGui.QValidator.Intermediate
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        combo = QtGui.QComboBox(editable=True)
        dir_validator = DirValidator(combo.lineEdit())
        combo.setValidator(dir_validator)
        combo.show()
        sys.exit(app.exec_())