我希望在QTableView列中有一个“特殊”QlineEdit
选择Qlinedit时,应选择整个文本(即有效)
数据应仅在返回键时提交
转义时,更改应还原为最后一个数据
仅当数据格式正确时,才应提交(在模型中设置)(参见功能检查数据)
这看起来并不复杂,但我无法让它工作。这里有一个粗略的例子(基于With PySide2 and QTableView how do i get multiple delegates in table view using pandas model?)
`
from PySide2 import QtWidgets
from PySide2.QtCore import (Qt, QAbstractTableModel, QModelIndex, QEvent,
QSortFilterProxyModel,
QTimer, Slot)
from PySide2.QtWidgets import QAbstractItemDelegate, QTableView, QAbstractItemView, QComboBox, QItemDelegate
class ScheduleModel(QAbstractTableModel):
def __init__(self, schedules_list=None, parent=None):
super(ScheduleModel, self).__init__(parent)
if schedules_list is None:
self.schedules_list = []
else:
self.schedules_list = schedules_list
def rowCount(self, index=QModelIndex()):
return len(self.schedules_list)
def columnCount(self, index=QModelIndex()):
return 3
def data(self, index, role=Qt.DisplayRole):
col = index.column()
if index.isValid():
if role in [Qt.DisplayRole, Qt.EditRole]:
value = self.schedules_list[index.row()][index.column()]
return str(value)
return None
def headerData(self, section, orientation, role):
# section is the index of the column/row.
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return ["A", "B", "edit"][section]
if orientation == Qt.Vertical and role == Qt.DisplayRole:
return str(section)
def setData(self, index, value, role=Qt.EditRole):
if role != Qt.EditRole:
return False
if index.isValid() and 0 <= index.row() < len(self.schedules_list):
self.schedules_list[index.row()][index.column()] = value
print("data set")
if self.data(index, Qt.DisplayRole) == value:
self.dataChanged.emit(index, index, (Qt.EditRole,))
return True
return False
def flags(self, index):
if 1 <= index.column() <= 5:
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
else:
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
class MyLineEdit(QtWidgets.QLineEdit):
def __init__(self, parent=None):
super(MyLineEdit, self).__init__(parent)
def focusInEvent(self, e):
print("focusin editor")
QTimer.singleShot(0, self.deselect)
QTimer.singleShot(0, self.selectAll)
def focusOutEvent(self, e):
print("focusout editor")
QTimer.singleShot(0, self.deselect)
class LineEditFileDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super().__init__(parent)
self.editor = None
# self.proxy=proxy
self.last_data=None
def paint(self, painter, option, index):
if isinstance(self.parent(), QtWidgets.QAbstractItemView):
self.parent().openPersistentEditor(index)
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
def createEditor(self, parent, option, index):
self.view = parent.parent()
self.editor=MyLineEdit(parent)
return self.editor
def setEditorData(self, editor, index):
print("setEditorData")
v = index.data(Qt.EditRole)
self.last_data = v
self.editor.setText(v)
def setModelData(self, editor, model, index):
ix = editor.text()
if not(ix):
return
model.setData(index, ix, Qt.EditRole)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
def check_data(self):
ix = self.editor.text()
print(ix)
if (ix) and(ix.lower()[0]=="s"):
return True
else:
return False
def eventFilter(self, editor, event):
# if event.type() in [QEvent.FocusAboutToChange, QEvent.FocusOut]:
# return False
if event.type() == QEvent.KeyPress:
key = event.key()
mod = int(event.modifiers())
if event.key() == Qt.Key_Return:
if self.check_data():
# self.last_data = self.editor.text()
self.commitData.emit(editor)
self.closeEditor.emit(editor, QAbstractItemDelegate.NoHint)
# # Don't emit closeEditor, select contents instead
editor.selectAll()
return False
if event.key() == Qt.Key_Escape:
#editor.setText( self.last_data)
self.closeEditor.emit(editor, QAbstractItemDelegate.NoHint)
return False
QtWidgets.QStyledItemDelegate.eventFilter(self, editor, event)
return False
class SchedulesViewer(QTableView):
def __init__(self, test_data=None, parent=None):
QTableView.__init__(self, parent)
# self.setContextMenuPolicy(Qt.CustomContextMenu)
# self.customContextMenuRequested.connect(self.schedule_context_menu)
self.schedule_model = ScheduleModel(test_data)
self.proxyModel = QSortFilterProxyModel(self)
self.proxyModel.setSourceModel(self.schedule_model)
self.proxyModel.setDynamicSortFilter(True)
self.setModel(self.proxyModel)
"""
HAVING LIMITS TO THE AMOUNT OF WIDGETS TABLE VIEW CAN HANDEL
"""
self.setItemDelegateForColumn(2, LineEditFileDelegate(self))
self.setSortingEnabled(True)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.horizontalHeader().setStretchLastSection(True)
self.verticalHeader().hide()
self.setSelectionMode(QAbstractItemView.SingleSelection)
self.proxyModel.sort(0, Qt.AscendingOrder)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setEditTriggers(QAbstractItemView.DoubleClicked)
self.setSelectionMode(QAbstractItemView.SingleSelection)
self.show()
if __name__ == "__main__":
import sys
from PySide2.QtWidgets import QApplication
app = QApplication(sys.argv)
test_data = [[x*3, idx, x] for idx,x in enumerate('abcde')]
addressWidget = SchedulesViewer(test_data)
addressWidget.show()
sys.exit(app.exec_())
`
目前没有回答
相关问题 更多 >
编程相关推荐