python - 当使用 QTreeView 的自定义 itemdelegate 时,如何自动开始在 QLineEdit 上进行编辑

标签 python pyqt5

我正在尝试为 QTreeview 设置一些自定义编辑器,并且几乎已经完成,但我仍然有 1 个小问题。

当用户在 TreeView 中输入标准编辑器时,所有文本都会被自动选择,并且任何进一步的击键都将开始编辑数据。

我似乎不知道如何在我的自定义编辑器上做到这一点。我虽然可以通过 setEditorData 方法在自定义编辑器中的 QLineedit 上调用 setFocus、selectAll 和 setCursorPosition,但这似乎不起作用。

我在这里缺少什么?

一个工作示例:

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt


class NspStringEdit(QtWidgets.QWidget):

    editingFinished = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(NspStringEdit, self).__init__(parent)
        self.resize(137, 25)
        self.setMaximumSize(QtCore.QSize(120, 25))

        self.Edit = QtWidgets.QLineEdit()
        self.Checkbox = QtWidgets.QCheckBox()
        self.Checkbox.setText("")

        self.main_layout = QtWidgets.QHBoxLayout()
        self.main_layout.addWidget(self.Edit)
        self.main_layout.addWidget(self.Checkbox)
        self.main_layout.setContentsMargins(2, 0, 0, 0)
        self.setLayout(self.main_layout)

        self.Checkbox.stateChanged.connect(self._on_state_change)
        self.Edit.editingFinished.connect(self._on_editingFinished)
        self.Checkbox.setFocusPolicy(Qt.NoFocus)
        self.setFocusPolicy(Qt.WheelFocus)

        self.setText(None)

    def _on_state_change(self):
        state = self.checkState()
        if state:
            self.Edit.setEnabled(True)
        else:
            self.Edit.setEnabled(False)
        self.editingFinished.emit()

    def _on_editingFinished(self):
        self.editingFinished.emit()

    def checkState(self):
        state = self.Checkbox.checkState()
        if state == Qt.Checked:
            return True
        else:
            return False

    def setText(self, val):
        self.Edit.setEnabled(True)
        if val is None:
            self.Checkbox.setCheckState(Qt.Unchecked)
            self.Edit.setEnabled(False)
        else:
            self.Edit.setText(val)
            self.Checkbox.setCheckState(Qt.Checked)

    def text(self):
        if self.checkState():
            return self.Edit.text()
        else:
            return None


class NspAbstractItemDelegate(QtWidgets.QStyledItemDelegate):

    def __init__(self):
        super(NspAbstractItemDelegate, self).__init__()

    def createEditor(self, parent, option, index):
        editor = NspStringEdit(parent)
        editor.setWindowFlags(QtCore.Qt.Popup)
        return editor

    def setEditorData(self, editor, index):
        data = index.data()
        editor.setText(data)

    def setModelData(self, editor, model, index):
        data = editor.text()
        txt = data
        model.setData(index, txt)

    def updateEditorGeometry(self, editor, option, index):
        r = option.rect
        height = r.bottom() - r.top()
        r.setY(r.y() + height)
        if editor.windowFlags() & QtCore.Qt.Popup and editor.parent() is not None:
            r.setTopLeft(editor.parent().mapToGlobal(r.topLeft()))
        editor.setGeometry(r)


class testTreeview(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(testTreeview, self).__init__(parent)
        self.mainTree = QtWidgets.QTreeView()
        self.lo = QtWidgets.QVBoxLayout()
        self.lo.addWidget(self.mainTree)
        self.setLayout(self.lo)
        self.model = QtGui.QStandardItemModel()
        self.mainTree.setModel(self.model)
        self.populate()
        self.mainTree.setItemDelegate(NspAbstractItemDelegate())

    def populate(self):

        row = [QtGui.QStandardItem('05/12/15'), QtGui.QStandardItem('07/13/18'), ]
        row2 = [QtGui.QStandardItem('12/21/21'), QtGui.QStandardItem('11/05/17'), ]
        all_rows = list(row)
        all_rows.extend(row2)
        for item in all_rows:
            item.setEditable(True)
        root = self.model.invisibleRootItem()
        root.appendRow(row)
        root.appendRow(row2)


if __name__ == "__main__":
    from PyQt5 import QtCore, QtGui, QtWidgets

    app = QtWidgets.QApplication([])
    volume = testTreeview()
    volume.show()
    app.exec_()

最佳答案

如果你想让QLineEdit编辑器获得焦点并可以直接编辑,那么你必须让QLineEdit成为NspStringEdit的focusProxy:

self.Edit = QtWidgets.QLineEdit()
<b>self.setFocusProxy(self.Edit)</b>

关于python - 当使用 QTreeView 的自定义 itemdelegate 时,如何自动开始在 QLineEdit 上进行编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58192234/

相关文章:

Python Pandas 从另一个观察结果中输入字符串值

python - python 2.7 交换的奇怪行为

Python3-Pyqt5如何通过异常或按退出按钮结束线程中的循环

python - pyqt - 将 qt 设计器中的子小部件放置在父级附近

python - dynamodb boto put_item 类型为 Map "M"

python - 在 Python DataFrame 中拆分字符串

python - 如何在 Django 中描述 URL - 仍然需要一个答案

python - 将 Chrome 标志与 QtWebEngine (PyQt5) 一起使用

python - WebView 组件忽略自定义字体

python - PyQt5:执行while循环后才会显示子窗口