PDA

View Full Version : QTreeView horizontal tab key navigation



maranos
29th April 2014, 15:44
Hi,

when the user presses TAB while editing an item in a QTreeView, the view closes the current editor and starts editing the item below. Is there a way to change this behavior so that the item on the right is edited? (similar to LibreOffice Calc and probably Excel)
I tried setting event filters and overwriting the event-function in the tree, the viewport and the editor (using a custom delegate), but I was not able to intercept this TAB event.

Below you will find a simple test script (in PyQt), without event filters.

Thanks



from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
#from PyQt4 import QtCore, QtGui as QtWidgets
#from PyQt4.QtCore import Qt

class TreeView(QtWidgets.QTreeWidget):
def __init__(self):
super().__init__()
self.setColumnCount(5)
for i in range(3):
item = QtWidgets.QTreeWidgetItem(["Some", "Test", "Strings"])
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled)
self.addTopLevelItem(item)


app = QtWidgets.QApplication([])
tree = TreeView()
tree.show()
app.exec_()

anda_skoa
29th April 2014, 17:11
If it should behave more like a spreadsheet, maybe use QTableView?

Cheers,
_

maranos
29th April 2014, 19:37
The test script looks like a table, but in the real application I need a tree structure.

ChrisW67
30th April 2014, 02:38
I think the correct approach here is to provide override QTreeView::moveCursor(), do something different for MoveNext and MovePrevious, and fall back to the base behaviour for the other options.

maranos
30th April 2014, 11:20
Thank you, this solves the problem!

Here is a simple implementation (not covering the cases where the next/previous index has a different parent):


def moveCursor(self, cursorAction, modifiers):
if cursorAction == QtWidgets.QAbstractItemView.MoveNext:
index = self.currentIndex()
if index.isValid():
if index.column()+1 < self.model().columnCount():
return index.sibling(index.row(), index.column()+1)
elif index.row()+1 < self.model().rowCount(index.parent()):
return index.sibling(index.row()+1, 0)
else:
return QtCore.QModelIndex()
elif cursorAction == QtWidgets.QAbstractItemView.MovePrevious:
index = self.currentIndex()
if index.isValid():
if index.column() >= 1:
return index.sibling(index.row(), index.column()-1)
elif index.row() >= 1:
return index.sibling(index.row()-1, self.model().columnCount()-1)
else:
return QtCore.QModelIndex()
super().moveCursor(cursorAction, modifiers)