我用的是定制的
QTableWidget
包含
QPlainTextEdit
s表示可编辑字段。我必须通过tab和箭头键切换单元格的代码现在与启用鼠标跟踪发生冲突。
按照我的习惯
Qplaintextedit公司
,我有
focusInEvent
要处理当您点击tab键、shift+tab键、箭头键等时发生的情况,如果它是其中之一,它将忽略该事件,因此
qtablewidget程序
可以应付。
在
qtablewidget程序
,按下其中一个键后,它将使用
self.selectCell(desiredRow, desiredColumn)
选择所需的单元格(在该函数使用
selectionModel
执行选择)。这触发了
OtherFocusReason
事件原因
Qplaintextedit公司
在
qtablewidget程序
,我刚用过
self.setMouseTracking(True)
试图跟踪光标悬停在哪个单元格上。不幸的是,这也引发了
其他原因
当鼠标通过它时,导致相同的代码运行,就像我通过键盘切换焦点一样。
有没有办法让我知道
其他原因
是由什么引起的?
下面是一些与键和焦点控件相关的选定位:
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)
我想另一种看待这一点的方法是,如何在选择期间发出特定的焦点原因?