pyqt pass focus to delegate editor

653 views Asked by At

My QStyledItemDelegate uses a QDialog (Qt.Popup) to display a QLineEdit and a QListWidget. I'm failing to have the focus set properly on the QLineEdit. The focus seems to remain on the QTreeView from which the editing began.

I've tried, -setFocus() and setFocusPolicy(Qt.StrongFocus) on the QDialog editor and the QLineEdit within -activateWindow() on the editor (although the pop is already on top)

my QDialog and QLineEdit subclasses:

class ValidatedLineEdit(QLineEdit):
def __init__(self, list_widget, parent=None):
    QLineEdit.__init__(self, parent)

    self._listW = list_widget
    self._parent = parent

    self.setFocusPolicy(Qt.StrongFocus)
    self.setFocus()
    self.activateWindow()

    validator = QRegExpValidator(QRegExp("[\w\*]*"), self)
    self.setValidator(validator)

def keyReleaseEvent(self, event):
    '''
    @param event  QKeyEvent
    '''
    self._listW.clear()
    text = self.text()
    reg_exp = QRegExp(text.replace('*', '.*'))

    self._listW.addItems(QStringList([a for a in self._parent._elementList if reg_exp.exactMatch(a)]))

    return super(ValidatedLineEdit, self).keyReleaseEvent(event)


class ValidatedFilterListDialog(QDialog):
def __init__(self, element_list=[], window_flag=Qt.Popup, parent=None):
    QDialog.__init__(self, parent, window_flag)

    self._elementList = element_list

    layout = QVBoxLayout(self)

    self._listW = QListWidget(self)
    self._lineE = ValidatedLineEdit(self._listW, parent=self)
    self._lineE.setFocus()

    self._listW.addItems(QStringList(sorted(self._elementList)))

    layout.addWidget(self._lineE)
    layout.addWidget(self._listW)

@property 
def value(self):
    return self._lineE.text()

@property 
def line_edit(self):
    return self._lineE

@property 
def list_widget(self):
    return self._listW

My delegate class,

class AddValidatedFilterDelegate(QStyledItemDelegate):
'''
A custom validator for the include/exclude items.
'''
def __init__(self, parent=None):
    QStyledItemDelegate.__init__(self, parent)
    self._parent = parent

def createEditor(self, parent, option, index):
    '''
    @param parent QWidget
    @param option QStyleOptionViewItem 
    @param index  QModelIndex 
    '''
    if not index.isValid():
        return 0
    if index.column() == 0: #only on the cells in the first column

        editor = generic.ValidatedFilterListDialog(element_list=sorted(index.model()._parent._elementList), parent=parent)
        editor.setFocusPolicy(Qt.StrongFocus)
        editor.activateWindow()
        editor.line_edit.setFocus()
        return editor

    return super(AddValidatedFilterDelegate, self).createEditor(parent, option, index)

def sizeHint(self, option, index):
    text = index.model().data(index)
    document = QTextDocument()
    document.setDefaultFont(option.font)
    document.setHtml(text)
    return QSize(document.idealWidth() + 5,
                 option.fontMetrics.height())


def setEditorData(self, editor, index):
    value = index.model().data(index, Qt.DisplayRole)
    editor.line_edit.setText(value)
    editor.line_edit.setFocus()


def setModelData(self, editor, model, index):
    model.setData(index, QVariant(editor.value))


def updateEditorGeometry(self, editor, option, index):

    top_left = self._parent.mapToGlobal(self._parent.rect().topLeft())
    x = top_left.x()
    y = top_left.y() + editor.rect().y()
    w = self._parent.width()

    editor.setGeometry(x, y, w, 400)

Anything stick out??

0

There are 0 answers