Я пытаюсь использовать пользовательский делегат для вызова пользовательских редакторов даты и времени для использования внутри qtreeview.Все, что я прочитал, говорит о том, что для того, чтобы виджет редактора отображался в правильном месте, поверх текущего индекса, вы повторно реализуете метод updateEditorGeometry и используете editor.setGeometry (option.rect) для установки позиции.
Я не могу понять это, хотя.Вот что у меня так далеко.При двойном щелчке по столбцу 1 в левом верхнем углу экрана отображается редактор.
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import Qt
import datetime
class NspDateEdit(QtWidgets.QWidget):
editingFinished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(NspDateEdit, self).__init__(parent)
# self.resize(137, 25)
# self.setMaximumSize(QtCore.QSize(120, 25))
self.date_edit = QtWidgets.QDateEdit()
self.date_edit.setCalendarPopup(True)
self.check_box = QtWidgets.QCheckBox()
self.check_box.setText("")
self.main_layout = QtWidgets.QHBoxLayout()
self.main_layout.addWidget(self.date_edit)
self.main_layout.addWidget(self.check_box)
self.main_layout.setContentsMargins(2, 0, 0, 0)
self.setLayout(self.main_layout)
self.check_box.stateChanged.connect(self._on_state_change)
self.date_edit.editingFinished.connect(self._on_editingFinished)
self.setDate(None)
def _on_state_change(self):
state = self.checkState()
if state:
current_date = self.date_edit.date()
current_date_py = current_date.toPyDate()
current_date_str = current_date_py.strftime('%Y-%m-%d')
if current_date_str == '2000-01-01':
new_date = datetime.datetime.now().date()
else:
new_date = current_date_py
self.setDate(new_date)
else:
self.setDate(None)
self.editingFinished.emit()
def _on_editingFinished(self):
self.editingFinished.emit()
def checkState(self):
state = self.check_box.checkState()
if state == Qt.Checked:
return True
else:
return False
def setDate(self, val):
self.date_edit.setEnabled(True)
if val is None:
self.check_box.setCheckState(Qt.Unchecked)
self.date_edit.setEnabled(False)
else:
self.date_edit.setDate(val)
self.check_box.setCheckState(Qt.Checked)
def date(self):
if self.checkState():
return self.date_edit.date().toPyDate()
else:
return None
class NspAbstractItemDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self):
super(NspAbstractItemDelegate, self).__init__()
def createEditor(self, parent, option, index):
editor = NspDateEdit()
editor.setWindowFlags(QtCore.Qt.Popup)
return editor
def setEditorData(self, editor, index):
data = index.data()
formatted = datetime.datetime.strptime(data, '%m/%d/%y').date()
editor.setDate(formatted)
def setModelData(self, editor, model, index):
data = editor.date()
txt = data.strftime('%m/%d/%y')
model.setData(index, txt)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
class testTreeview(QtWidgets.QWidget):
def __init__(self, parent=None):
super(testTreeview, self).__init__(parent)
self.mainTree = QtWidgets.QTreeView()
self.testButton = QtWidgets.QPushButton()
self.lo = QtWidgets.QVBoxLayout()
self.lo.addWidget(self.mainTree)
self.lo.addWidget(self.testButton)
self.setLayout(self.lo)
self.model = QtGui.QStandardItemModel()
self.mainTree.setModel(self.model)
self.populate()
self.testButton.clicked.connect(self._on_clicked_button)
self.mainTree.setItemDelegateForColumn(0, NspAbstractItemDelegate())
def _on_clicked_button(self):
self.mainTree.edit(self.mainTree.currentIndex()) #, QtWidgets.QAbstractItemView.EditTrigger(), None)
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_()