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

Reply via email to