QTableView Selecion Change
Asked Answered
B

2

6

Been googling around for some time on this one but I can't seem to find anything. Need the signal for QTableView on a selection change. Tried tbl_view.itemSelectionChanged.connect(self.select_row) but the compiler complains this doesn't exist. I also need to retrieve the data from the row that is selected. Can someone please point me in the right direction?

Berley answered 12/10, 2018 at 11:1 Comment(0)
A
8

itemSelectionChanged is a QTableWidget signal since in that class the concept of item exists, but in QTableView it does not. In the case of QTableView, QListView and QTreeView have the method called selectionModel() that returns a model that tracks the selected elements, and that model has a signal called selectionChanged() that is issued whenever there is a change in the selection, for example:

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        table_view = QtWidgets.QTableView()
        self.setCentralWidget(table_view)

        model = QtGui.QStandardItemModel(5, 5, self)
        table_view.setModel(model)

        for i in range(model.rowCount()):
            for j in range(model.columnCount()):
                it = QtGui.QStandardItem(f"{i}-{j}")
                model.setItem(i, j, it)

        selection_model = table_view.selectionModel()
        selection_model.selectionChanged.connect(self.on_selectionChanged)

    @QtCore.pyqtSlot('QItemSelection', 'QItemSelection')
    def on_selectionChanged(self, selected, deselected):
        print("selected: ")
        for ix in selected.indexes():
            print(ix.data())

        print("deselected: ")
        for ix in deselected.indexes():
            print(ix.data())


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
Acetum answered 12/10, 2018 at 11:51 Comment(1)
Thanks, as usual, eyllanesc!Berley
E
3

You can refer to this example.

import sys
from PyQt5 import QtWidgets, QtCore, QtGui


class Message(QtCore.QAbstractItemModel):
    def __init__(self):
        super().__init__()

        self.messageList = []

    def addMessage(self, typeName, data):
        self.messageList.append({"type": typeName,
                                 "data": data})

    def data(self, index, role):

        if not index.isValid():
            return None

        if role != QtCore.Qt.DisplayRole:
            return None

        item = self.messageList[index.row()]

        if index.column() == 0:
            return str(item["type"])
        else:
            return str(item["data"])

    def headerData(self, section, orientation, role):
        if orientation == QtCore.Qt.Horizontal:
            if role == QtCore.Qt.DisplayRole:
                if section == 0:
                    return "type"
                else:
                    return "data"

        return None

    def parent(self, index):
        if not index.isValid():
            return QtCore.QModelIndex()

        return QtCore.QModelIndex()

    def index(self, row, column, parent):
        if not self.hasIndex(row, column, parent):
            return QtCore.QModelIndex()
        else:
            return self.createIndex(row, column)

    def flags(self, index):
        if not index.isValid():
            return QtCore.Qt.NoItemFlags

        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def columnCount(self, parent):
        return 2

    def rowCount(self, parent):
        return len(self.messageList)


class FormMessageJournal(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.layout = QtWidgets.QVBoxLayout()

        self.messageTable = QtWidgets.QTableView(self)
        self.messageTable.clicked.connect(self.onClickedRow)
        self.messageList = Message()
        self.messageList.addMessage("Send1", "Hello1")
        self.messageList.addMessage("Send2", "Hello2")
        self.messageList.addMessage("Send3", "Hello3")
        self.messageList.addMessage("Send4", "Hello4")
        self.messageTable.setModel(self.messageList)
        self.layout.addWidget(self.messageTable)

        self.setLayout(self.layout)

    def onClickedRow(self, index=None):
        print(index.row(), index.column(), self.messageList.data(index, QtCore.Qt.DisplayRole))


if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = FormMessageJournal()
    widget.show()

    sys.exit(app.exec_())
Elodia answered 12/10, 2018 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.