我有一个QTableView
,我在上面重写了keyPressEvent
方法,例如当用户按下右下角的tab键时,一个新行被附加到底层(pandas)模型。完成此操作后,我希望当前索引位于新的右下角。这是一个原则上应该完成这项工作的示例:
from PyQt5 import QtCore, QtWidgets
class DL50TableView(QtWidgets.QTableView):
def keyPressEvent(self, event):
key = event.key()
model = self.model()
current_index = self.currentIndex()
row = current_index.row()
column = current_index.column()
if key == QtCore.Qt.Key_Tab:
if column == model.columnCount() - 1 and row == model.rowCount() - 1:
model.insertRows(model.rowCount())
index = model.index(model.rowCount() - 1,model.columnCount() - 1)
self.setCurrentIndex(index)
elif key == QtCore.Qt.Key_Backspace:
if column == 0 and row == model.rowCount() - 1:
model.removeRows(model.rowCount() - 1)
index = model.index(model.rowCount() - 1,0)
self.setCurrentIndex(index)
super(DL50TableView, self).keyPressEvent(event)
import pandas as pd
from PyQt5 import QtCore, QtGui
class DL50Model(QtCore.QAbstractTableModel):
def __init__(self, *args, **kwargs):
super(DL50Model,self).__init__(*args, **kwargs)
self._data = pd.DataFrame([self.default_line()], columns=['include',
'dose',
'response',
'nominal',
'log10(dose)',
'contrib.\ndae',
'prob.\nof\nresponse',
'likelihood\ncontrib.',
'prob.\nof\nresponse\n(sub)',
'likelihood\ncontrib.\n(sub)',
'prob.\nof\nresponse\n(over)',
'likelihood\ncontrib.\n(over)'])
def columnCount(self, parent=None):
return len(self._data.columns)
def data(self, index, role):
if not index.isValid():
return False
row = index.row()
col = index.column()
if role == QtCore.Qt.BackgroundRole and col >= 3:
return QtGui.QBrush(QtCore.Qt.gray)
elif role == QtCore.Qt.CheckStateRole and col in [0,2,3]:
return self._data.iloc[row][col]
elif role == QtCore.Qt.DisplayRole:
if col in [0,2,3]:
return None
return str(self._data.iloc[row][col])
return None
def default_line(self):
return [False, 0.0,False, False, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
def insertRows(self, position, rows=1, index=QtCore.QModelIndex()):
"""Insert row(s) into the model.
Args:
position (int): the position of the row(s) to iunsert
rows (int): the number of rows to insert
index (QModelIndex): the parent index
"""
self.beginInsertRows(QtCore.QModelIndex(), position, position + rows - 1)
default = [self.default_line()]*rows
lines = pd.DataFrame(default, columns=self._data.columns)
self._data = pd.concat([self._data.iloc[:position], lines, self._data.iloc[position:]]).reset_index(drop=True)
self.endInsertRows()
return True
def removeRows(self, position, rows=1, parent=QtCore.QModelIndex()):
"""Remove row(s) from the model.
Args:
position (int): the position of the row(s) to delete
rows (int): the number of rows to delete
index (QModelIndex): the parent index
"""
self.beginRemoveRows(QtCore.QModelIndex(), position, position + rows - 1)
print('BEFORE', len(self._data.index))
self._data.drop(self._data.index[position:position+rows], inplace=True)
print('AFTER', len(self._data.index))
self.endRemoveRows()
return True
def rowCount(self, parent=None):
return len(self._data.index)
运行该代码时,当我按 Tab 但时,实际上会附加一个新行,currentIndex
设置为 (0,0)
而不是我编写的代码所期望的右下角。你知道我的 View /模型有什么问题吗?
最佳答案
通过重写 keyPressEvent 方法,因为在实现自定义逻辑后,您将调用选项卡用于移动 currentIndex 的默认代码,并且由于您的 currentIndex 位于 bottonRight 中,因此它将移动到左上角。
一种可能的解决方案是使用“return”语句阻止默认行为运行:
# ...
if key == QtCore.Qt.Key_Tab:
if column == model.columnCount() - 1 and row == model.rowCount() - 1:
model.insertRows(model.rowCount())
index = model.index(model.rowCount() - 1, model.columnCount() - 1)
self.setCurrentIndex(index)
<b>return</b>
# ...
关于python - QTableView 的 setCurrentIndex 将 currentIndex 放置到错误的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62592211/