Question

I'm using a QTableView to display contents of a QSqlTableModel along with using a QSortFilterProxyModel to filter the records. In the following code I've managed to get the selected text to be displayed when a user clicks the cell (regardless if a filter is applied or not). However, it is always 1 click behind, the first click after start causes an IndexError: pop from empty list and when a new column is selected within the same row nothing happens.

I've tried selecting an index after I initialize the table, didn't seems to do anything. I'm out of ideas of what to try next?

class TableViewer(QtGui.QWidget):

    self.model =  QSqlTableModel()
    self._proxyModel = QtGui.QSortFilterProxyModel()
    self._proxyModel.setSourceModel(self.model)

    self.tv= QTableView()
    self.tv.setModel(self._proxyModel)

   '''Call-able filter - pass in string to filter everything that doesn't match string'''
    QtCore.QObject.connect(self.textEditFilterBox,  QtCore.SIGNAL("textChanged(QString)"),     self._proxyModel.setFilterRegExp)


     def getItem(self):
         '''Retruns item text of selected item'''
         index = self.selectionModel.selectedIndexes().pop()
         if index.isValid():
             row = index.row()
             column = index.column()
             model = index.model()
             if hasattr(model, 'mapToSource'):
                 #proxy model
                 modelIndex = model.mapToSource(index)
                 print (modelIndex.row(), modelIndex.column())
                 return self.model.record(modelIndex.row()).field(modelIndex.column()).value().toString()
         return self.model.record(row).field(column).value().toString()

class MainWindow(QtGui.QMainWindow):

    #initialize TableViewer

    self.tblViewer.connect(self.tblViewer.tv.selectionModel(),
            SIGNAL(("currentRowChanged(QModelIndex,QModelIndex)")),
            self.tblItemChanged)

    def tblItemChanged(self, index):
        '''display text of selected item '''
        text = self.tblViewer.getItem()
        print(text)
Was it helpful?

Solution

and when a new column is selected within the same row nothing happens.

That's because you are using currentRowChanged signal. That signal won't be fired if you select a column in the same row. You should use currentChanged signal. (and, you should use new style connections)

And, if you are after just the data, you don't need those stuff to get the non-proxy QModelIndex and then ask the model, etc. A QModelIndex has a convenience method .data that is just for this purpose. Besides, the signal will send you the selected index, you don't need extra work for that. This makes your code as simple as this: (note: getItem method is not needed)

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        #initialize TableViewer
        self.tblViewer.tv.selectionModel().currentChanged.connect(self.tblItemChanged)

    def tblItemChanged(self, current, previous):
        '''display text of selected item '''
        # `data` defaults to DisplayRole, e.g. the text that is displayed
        print(current.data().toString()) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top