python - 为 QTreeView 使用自定义 itemdelegate 时,如何自动开始在 QLineEdit 上进行编辑
问题描述
我正在尝试为 QTreeview 设置一些自定义编辑器,并且几乎将其关闭,但我仍然有 1 个小问题。
当用户在树形视图中输入标准编辑器时,所有文本都被自动选择,任何进一步的击键都将开始编辑数据。
我似乎无法弄清楚如何在我的自定义编辑器上做到这一点。我虽然可以从 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()
self.setFocusProxy(self.Edit)
推荐阅读
- reactjs - React/Redux 只需单击即可执行多个引用
- sql - 如何将一个值拆分为多行,然后将其更新到 postgresql 中的同一张表中?
- java - Cadence ListOpenWorkflowExecutions 始终返回零
- c - 了解C x86优化一个小函数
- java - 在java中查找欧拉数的问题
- io - 如何使用 CGAL::read_ply_points() 读取二进制层文件?
- javascript - 访问 axios -vuejs 返回的观察者对象
- css - 将背景图像 css 用于引导图标
- javascript - 自定义类扩展 Array 而不使用扩展语法
- angular - Angular PrimeNG - 从输入中获取逗号分隔值并存储为数组