【问题标题】:How to intercept key events when editing a cell in QTableWidget/QTableViewQTableWidget/QTableView编辑单元格时如何拦截关键事件
【发布时间】:2017-01-10 10:18:15
【问题描述】:

我需要拦截用户在QTableWidget 中编辑单元格时发出的关键事件。有没有一种简单的方法可以做到这一点?我正在考虑安装事件过滤器,但我不知道如何获取对编辑器小部件的引用。还是我需要以某种方式重新实现QItemDelegate?这对我来说似乎有点矫枉过正,不知道该怎么做,究竟需要重新实现什么。还是有别的办法?

我需要这个,因为例如当用户按下左/右光标键时,我想跳到左/右的下一个单元格。

【问题讨论】:

  • 你确定你想要这种行为吗?这将使得在编辑期间无法在文本内移动(例如删除较早的字符)。
  • 实际上这是 MS Excel 所做的。当我知道如何做到这一点时,我可以做更多的微调,例如当您按 F2 时,您可以在编辑的文本中使用箭头等移动。但是似乎我已经有了解决方案。我会尽快发布。

标签: qt pyqt pyside


【解决方案1】:

看来我终于弄明白了,它完全按照我的需要工作。这是使用覆盖QStyledItemDelegate 的 PySide 解决方案(C++ 类似)。一开始我觉得这有点矫枉过正,但并没有那么糟糕。

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)

【讨论】:

    【解决方案2】:

    或者你也可以像这样使用 cellClicked 信号:

      connect(ui->tbControl,SIGNAL(cellClicked(int,int)),this,SLOT(detectCellSelectionGraph(int,int)));
    

    【讨论】:

    • 什么?如何?你确定吗?
    猜你喜欢
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 2012-01-18
    • 2012-01-15
    • 2011-04-23
    • 2021-10-10
    • 2020-12-25
    • 1970-01-01
    相关资源
    最近更新 更多