Hello,
In my application I have a tableview in which the user must be able to scroll
through the (editable) cells by using Tab, Key_right and Return. Columns that
are disabled must be skipped. When the lower right cell is reached, a new row
must be created when one of the before mentioned keys is pressed. To implement
this, I reimplemented QTableView and the event and keyPressEvent event
handlers. This works OK in a 'non-graphics' mode i.e. QTableView is not
'painted' in a QGraphicsView. In this case, pressing one of the keys results in
moving the cursor to the next cell or row.
As soon as the tableview is part of an QGraphicsView, pressing Return results
in moving the cursor to the end of the row. This is due to the fact that event
is called twice for a single Return press. It is unclear to me why this is
happening. Anyone any ideas? I enclose the code. Calling main() runs the code
in 'non-graphics' mode, calling maing() runs it in 'graphics' mode.
Python v. 2.6.5
PyQt v. 4.6.2
Peter
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import PyQt4.QtCore
from PyQt4 import QtCore
from PyQt4 import QtGui
import sys
my_array = [[1, "m", 12.0, 3.0], [2, "f", 10.0, 11.0]]
def maing():
app = QApplication(sys.argv)
scene = QtGui.QGraphicsScene()
scene.setSceneRect(0,0,300,200)
view = QtGui.QGraphicsView()
view.setScene(scene)
view.show()
w = MyWindow()
t = scene.addWidget(w)
layout = QtGui.QGraphicsLinearLayout()
layout.addItem(t)
# w.show()
sys.exit(app.exec_())
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
class MyWindow(QTableView):
def __init__(self, *args):
QTableView.__init__(self, *args)
self.tablemodel = MyTableModel(my_array, self)
self.setModel(self.tablemodel)
self.setItemDelegate(MyDelegate(self))
hh = self.horizontalHeader()
hh.setStretchLastSection(True)
self.resizeColumnsToContents()
def event(self, event):
if (event.type() == QtCore.QEvent.ShortcutOverride) and \
((event.key() == QtCore.Qt.Key_Tab) or (event.key() ==
QtCore.Qt.Key_Return)):
print "Type: ", event.type()
print "In event", id(event)
end = self.endOfTable()
if end:
self.insertRow()
if (event.key() == QtCore.Qt.Key_Return):
self.toNextCellOrRow()
return True
else:
return super(MyWindow, self).event(event)
def keyPressEvent(self, event):
if (event.type() == QtCore.QEvent.KeyPress) and (event.key() ==
QtCore.Qt.Key_Right):
end = self.endOfTable()
print "in keypress"
if end:
self.insertRow()
self.toNextCellOrRow()
else:
return super(MyWindow, self).keyPressEvent(event)
def insertRow(self):
nr_rows = self.tablemodel.rowCount()
self.tablemodel.beginInsertRows(QtCore.QModelIndex(),nr_rows,
nr_rows)
self.tablemodel.endInsertRows()
my_array.append([9, "f", 99.0, 99.0])
def toNextCellOrRow(self):
section = self.currentIndex().column()
current_row = self.currentIndex().row()
#nr_rows = self.tablemodel.rowCount()
cursor_index = self.moveCursor(QAbstractItemView.MoveRight,
Qt.NoModifier)
if (section == cursor_index.column()):
index =
self.tablemodel.createIndex(cursor_index.row()+1, 0)
self.setCurrentIndex(index)
else:
self.setCurrentIndex(cursor_index)
def endOfTable(self):
section = self.currentIndex().column()
current_row = self.currentIndex().row()
nr_rows = self.tablemodel.rowCount()
cursor_index = self.moveCursor(QAbstractItemView.MoveRight,
Qt.NoModifier)
cursor_section = cursor_index.column()
if (current_row == nr_rows -1) and (section == cursor_section):
return True
return False
class MyTableModel(PyQt4.QtCore.QAbstractTableModel):
NR_COLS = 4
FISHNR, GENDER, WEIGHT, LENGTH = range(NR_COLS)
def __init__(self, datain, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.arraydata = datain
self.editable = {}
self.editable[MyTableModel.FISHNR] = True
self.editable[MyTableModel.GENDER] = True
self.editable[MyTableModel.WEIGHT] = False
self.editable[MyTableModel.LENGTH] = True
def rowCount(self, parent=None):
return len(self.arraydata)
#return 2
def columnCount(self, parent=None):
#return len(self.arraydata[0])
return 4
def data(self, index, role):
if not index.isValid():
return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
return QVariant(self.arraydata[index.row()][index.column()])
def headerData(self, section, orientation,
role=PyQt4.QtCore.Qt.DisplayRole):
#self.log.debug("headerdata called, section:%d" % section)
if role == PyQt4.QtCore.Qt.TextAlignmentRole:
if orientation == PyQt4.QtCore.Qt.Horizontal:
return
PyQt4.QtCore.QVariant(int(PyQt4.QtCore.Qt.AlignLeft|PyQt4.QtCore.Qt.AlignVCenter))
return
PyQt4.QtCore.QVariant(int(PyQt4.QtCore.Qt.AlignRight|PyQt4.QtCore.Qt.AlignVCenter))
if role != PyQt4.QtCore.Qt.DisplayRole:
return PyQt4.QtCore.QVariant()
if orientation == PyQt4.QtCore.Qt.Horizontal:
if section == MyTableModel.FISHNR:
return PyQt4.QtCore.QVariant("Fishnr")
if section == MyTableModel.GENDER:
return PyQt4.QtCore.QVariant("Gender")
if section == MyTableModel.WEIGHT:
return PyQt4.QtCore.QVariant("Weight")
if section == MyTableModel.LENGTH:
return PyQt4.QtCore.QVariant("Length")
return PyQt4.QtCore.QVariant(int(section + 1))
def flags(self, index):
if not index.isValid():
return QtCore.Qt.ItemIsEnabled
section = index.column()
if self.editable[section]:
return
QtCore.Qt.ItemFlags(QtCore.QAbstractTableModel.flags(self,
index)|QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsEnabled)
else:
return QtCore.Qt.NoItemFlags
def get_editable(self):
return self.editable
class MyDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(MyDelegate, self).__init__(parent)
self.parent = parent
def createEditor(self, parent, option, index):
if index.column() == MyTableModel.FISHNR:
editor = QtGui.QLineEdit(parent)
editor.setValidator(QtGui.QIntValidator(1, 9999, parent))
#self.connect(editor, SIGNAL("returnPressed()"),
# self.commitAndCloseEditor)
return editor
elif index.column() == MyTableModel.WEIGHT:
editor = QtGui.QLineEdit(parent)
#self.connect(editor, SIGNAL("returnPressed()"),
# self.commitAndCloseEditor)
return editor
elif index.column() == MyTableModel.LENGTH:
editor = QtGui.QLineEdit(parent)
editor.setValidator(QtGui.QIntValidator(0.000001,99.999999, parent))
#self.connect(editor, SIGNAL("returnPressed()"),
# self.commitAndCloseEditor)
return editor
elif index.column() == MyTableModel.GENDER:
editor = QtGui.QLineEdit(parent)
#self.connect(editor, SIGNAL("returnPressed()"),
# self.commitAndCloseEditor)
return editor
else:
return QtGui.QStyledItemDelegate.createEditor(self,parent, option,
index)
def setEditorData(self, editor, index):
if index.isValid():
text = index.model().data(index,
QtCore.Qt.DisplayRole).toString()
editor.setText(text)
def setModelData(self, editor, model, index):
#pass
model.setData(index, editor.text())
if __name__ == "__main__":
main()
Peter HJ van der Kamp
Software developer
Wageningen IMARES, afd. Visserij
Postbus 68
1970 AB IJmuiden
Tel. 0317-487176
_______________________________________________
PyQt mailing list [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt