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 PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt