在QTableWidget/QTableView中编辑单元格时如何截获关键事件
我需要截获用户在在QTableWidget/QTableView中编辑单元格时如何截获关键事件,qt,pyqt,pyside,Qt,Pyqt,Pyside,我需要截获用户在QTableWidget中编辑单元格时发出的关键事件。有没有一个简单的方法可以做到这一点?我正在考虑安装事件过滤器,但我不知道如何获取对编辑器小部件的引用。或者我是否需要以某种方式重新实现QItemDelegate?对我来说,这似乎是过火了,而且不确定如何做到这一点,到底需要重新实现什么。还是有别的办法 我之所以需要它,是因为例如,当用户按下左/右光标键时,我想跳到左/右的下一个单元格 看来我终于找到了答案,它完全符合我的需要。这里是PySide中的一个解决方案(C++类似),使
QTableWidget
中编辑单元格时发出的关键事件。有没有一个简单的方法可以做到这一点?我正在考虑安装事件过滤器,但我不知道如何获取对编辑器小部件的引用。或者我是否需要以某种方式重新实现QItemDelegate
?对我来说,这似乎是过火了,而且不确定如何做到这一点,到底需要重新实现什么。还是有别的办法
我之所以需要它,是因为例如,当用户按下左/右光标键时,我想跳到左/右的下一个单元格 看来我终于找到了答案,它完全符合我的需要。这里是PySide中的一个解决方案(C++类似),使用
QStyledItemDelegate
的重写。在我看来,一开始这似乎是矫枉过正,但并没有那么糟糕
fromPySide import QtCore, QtGui
class LineEditDelegate(QtGui.QStyledItemDelegate):
moveCurrentCellBy = QtCore.Signal(int, int)
def __init__(self, parent=None):
super(LineEditDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
self.editor = QtGui.QLineEdit(parent)
self.editor.setFrame(False)
self.editor.installEventFilter(self)
return self.editor
def setEditorData(self, editor, index):
value = index.model().data(index, QtCore.Qt.EditRole)
editor.setText(value)
def setModelData(self, editor, model, index):
value = editor.text()
model.setData(index, value, QtCore.Qt.EditRole)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
def eventFilter(self, target, event):
if target is self.editor:
if event.type() == QtCore.QEvent.KeyPress:
moveCell, row, column = False, 0, 0
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter, QtCore.Qt.Key_Down):
moveCell, row, column = True, 1, 0
if event.key() in (QtCore.Qt.Key_Right, QtCore.Qt.Key_Tab):
moveCell, row, column = True, 0, 1
if event.key() in (QtCore.Qt.Key_Left, QtCore.Qt.Key_Backtab):
moveCell, row, column = True, 0, -1
if event.key() == QtCore.Qt.Key_Up:
moveCell, row, column = True, -1, 0
if moveCell:
self.commitData.emit(self.editor)
self.closeEditor.emit(self.editor, QtGui.QAbstractItemDelegate.NoHint)
self.moveCurrentCellBy.emit(row, column)
return True
return False
class TableWidget(QtGui.QTableWidget):
def __init__(self, parent=None):
super(TableWidget, self).__init__(parent)
delegate = LineEditDelegate()
delegate.moveCurrentCellBy.connect(self.moveCurrentCellBy)
self.setItemDelegate(delegate)
def moveCurrentCellBy(self, rowStep, columnStep):
row = self.currentRow() + rowStep
column = self.currentColumn() + columnStep
if row >= self.rowCount():
self.setRowCount(row + 1)
if column >= self.columnCount():
self.setColumnCount(column + 1)
self.setCurrentCell(row, column)
看来我终于找到了答案,它完全符合我的需要。这里是PySide中的一个解决方案(C++类似),使用
QStyledItemDelegate
的重写。在我看来,一开始这似乎是矫枉过正,但并没有那么糟糕
fromPySide import QtCore, QtGui
class LineEditDelegate(QtGui.QStyledItemDelegate):
moveCurrentCellBy = QtCore.Signal(int, int)
def __init__(self, parent=None):
super(LineEditDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
self.editor = QtGui.QLineEdit(parent)
self.editor.setFrame(False)
self.editor.installEventFilter(self)
return self.editor
def setEditorData(self, editor, index):
value = index.model().data(index, QtCore.Qt.EditRole)
editor.setText(value)
def setModelData(self, editor, model, index):
value = editor.text()
model.setData(index, value, QtCore.Qt.EditRole)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
def eventFilter(self, target, event):
if target is self.editor:
if event.type() == QtCore.QEvent.KeyPress:
moveCell, row, column = False, 0, 0
if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter, QtCore.Qt.Key_Down):
moveCell, row, column = True, 1, 0
if event.key() in (QtCore.Qt.Key_Right, QtCore.Qt.Key_Tab):
moveCell, row, column = True, 0, 1
if event.key() in (QtCore.Qt.Key_Left, QtCore.Qt.Key_Backtab):
moveCell, row, column = True, 0, -1
if event.key() == QtCore.Qt.Key_Up:
moveCell, row, column = True, -1, 0
if moveCell:
self.commitData.emit(self.editor)
self.closeEditor.emit(self.editor, QtGui.QAbstractItemDelegate.NoHint)
self.moveCurrentCellBy.emit(row, column)
return True
return False
class TableWidget(QtGui.QTableWidget):
def __init__(self, parent=None):
super(TableWidget, self).__init__(parent)
delegate = LineEditDelegate()
delegate.moveCurrentCellBy.connect(self.moveCurrentCellBy)
self.setItemDelegate(delegate)
def moveCurrentCellBy(self, rowStep, columnStep):
row = self.currentRow() + rowStep
column = self.currentColumn() + columnStep
if row >= self.rowCount():
self.setRowCount(row + 1)
if column >= self.columnCount():
self.setColumnCount(column + 1)
self.setCurrentCell(row, column)
或者,您也可以使用如下信号:
connect(ui->tbControl,SIGNAL(cellClicked(int,int)),this,SLOT(detectCellSelectionGraph(int,int)));
或者,您也可以使用如下信号:
connect(ui->tbControl,SIGNAL(cellClicked(int,int)),this,SLOT(detectCellSelectionGraph(int,int)));
你确定你想要那种行为吗?这将使编辑过程中无法在文本中移动(例如,删除较早的字符)。实际上,MS Excel就是这样做的。当我知道如何进行此操作时,我可以进行更多微调,例如,当您按下F2键时,您可以在编辑的文本中使用箭头移动,等等。不过,我似乎已经找到了解决方案。我很快就会发布。你确定你想要这种行为吗?这将使编辑过程中无法在文本中移动(例如,删除较早的字符)。实际上,MS Excel就是这样做的。当我知道如何进行此操作时,我可以进行更多微调,例如,当您按下F2键时,您可以在编辑的文本中使用箭头移动,等等。不过,我似乎已经找到了解决方案。我很快就会把它寄出去。什么?怎么用?你确定吗?什么?怎么用?你确定吗?