QTableView 选择改变

QTableView Selecion Change

在这个问题上谷歌搜索了一段时间,但我似乎找不到任何东西。在选择更改时需要 QTableView 的信号。尝试 tbl_view.itemSelectionChanged.connect(self.select_row) 但编译器抱怨这不存在。我还需要从所选行中检索数据。有人可以给我指出正确的方向吗?

可以参考这个例子

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_())

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() 在选择发生变化时发出,例如:

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_())