我正在使用一个自定义QTableWidget
,其中包含QPlainTextEdit
个可编辑字段。我必须通过Tab和方向键切换单元格的代码现在与启用鼠标跟踪冲突。
在我的自定义QPlainTextEdit
中,我有focusInEvent
处理当您按下Tab,Shift + Tab,方向键等时发生的情况。如果是其中之一,它将被忽略事件,以便QTableWidget
可以处理。
在QTableWidget
中,按下这些键之一后,它将使用self.selectCell(desiredRow, desiredColumn)
选择所需的单元格(该功能使用selectionModel
进行选择)。这会触发OtherFocusReason
QPlainTextEdit
事件原因
在QTableWidget
中,我只是使用self.setMouseTracking(True)
来尝试跟踪光标悬停在哪个单元格上。不幸的是,当鼠标经过OtherFocusReason
时,它也会触发OtherFocusReason
,从而导致运行与通过键盘切换焦点时相同的代码。
有什么方法可以检测到class QMultilineTableWidget(QtWidgets.QTableWidget):
def __init__(self, x=1, y=1, parent=None, *args, **kwargs):
super(QMultilineTableWidget, self).__init__(*args, **kwargs)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setFocusPolicy(QtCore.Qt.NoFocus)
self.setMouseTracking(True)
def selectCell(self, row, column, multi=False):
"""Select an individual cell."""
index = self.model().index(row, column)
if multi:
selectionType = QtCore.QItemSelectionModel.Select
else:
selectionType = QtCore.QItemSelectionModel.SelectCurrent
self.selectionModel().setCurrentIndex(index, selectionType)
def keyPressEvent(self, event):
"""Custom key press events for navigating the table."""
currentRow = self.currentRow()
currentColumn = self.currentColumn()
totalRows = self.rowCount()
totalColumns = self.columnCount()
key = event.key()
desiredRow = currentRow
desiredColumn = currentColumn
#Navigate with keys
if key == QtCore.Qt.Key_Up:
desiredRow = max(currentRow-1, 0)
if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter, QtCore.Qt.Key_Down):
desiredRow = min(currentRow+1, totalRows-1)
if key == QtCore.Qt.Key_Left:
desiredRow, desiredColumn = self._getNextEditableCell(currentRow, currentColumn, reverse=True, allowNewRows=False)[1:]
if key == QtCore.Qt.Key_Right:
desiredRow, desiredColumn = self._getNextEditableCell(currentRow, currentColumn, allowNewRows=False)[1:]
#Move back or forwards with tab
#TODO: move to next editable text
if key == QtCore.Qt.Key_Tab:
desiredRow, desiredColumn = self._getNextEditableCell(currentRow, currentColumn)[1:]
if key == QtCore.Qt.Key_Backtab:
desiredRow, desiredColumn = self._getNextEditableCell(currentRow, currentColumn, reverse=True)[1:]
self.selectCell(desiredRow, desiredColumn)
class _QMultilineTableTextEdit(QtWidgets.QPlainTextEdit):
mouseClickEnter = QtCore.Signal(QtWidgets.QTextEdit)
def __init__(self, text='', parent=None, *args, **kwargs):
super(_QMultilineTableTextEdit, self).__init__(text, parent=None, *args, **kwargs)
self.setParent(parent)
self.setFrameStyle(QtWidgets.QFrame.NoFrame)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
def focusInEvent(self, event):
"""Handle what happens when the widget is selected."""
#Send signal to update table position
#We check TabFocusReason anyway, but the custom tab actually causes OtherFuocusReason
if event.reason() in (QtCore.Qt.TabFocusReason, QtCore.Qt.BacktabFocusReason, QtCore.Qt.OtherFocusReason):
self.selectAll()
#Set cursor to end of text
elif event.reason() != QtCore.Qt.MouseFocusReason:
cursor = self.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
self.setTextCursor(cursor)
self.setEdited(False)
return super(_QMultilineTableTextEdit, self).focusInEvent(event)
def keyPressEvent(self, event):
"""Override key presses to see what should be sent to the parent widget instead."""
key = event.key()
modifiers = QtWidgets.QApplication.keyboardModifiers()
ctrlModifier = modifiers & QtCore.Qt.ControlModifier
shiftModifier = modifiers & QtCore.Qt.ShiftModifier
altModifier = modifiers & QtCore.Qt.AltModifier
if key in (QtCore.Qt.Key_Control, QtCore.Qt.Key_Shift, QtCore.Qt.Key_Alt):
return
#Only allow enter if it's shift+enter, otherwise send to parent widget
if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter) and not shiftModifier:
return event.ignore()
#Always send tab to the parent widget
if key in (QtCore.Qt.Key_Tab, QtCore.Qt.Key_Backtab):
return event.ignore()
if key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down, QtCore.Qt.Key_Left, QtCore.Qt.Key_Right):
return event.ignore()
return super(_QMultilineTableTextEdit, self).keyPressEvent(event)
是由什么引起的吗?
以下是一些与按键和焦点控制相关的位:
{{1}}
我认为看待这种情况的另一种方法是,在选择过程中如何发出特定的焦点原因?