当 QTableView 中的 adding/deleating 行时如何禁用 select 行行为

how to diseable select row behavior when adding/deleating a row in QTableView

我有一个带有 insert/deleate 行方法的子类 QAbstractTableModel

在主要部分 window 我有一个方法 insert_data 可以在当前选中单元格时插入一个字符串 (我打开了单选)
这是我想要更改的行为:
当我使用子类 QAbstractTableModelsetData 方法在单元格中插入一个值时 或者 insert_data
并删除该行 ---> 上面的行被选中(该行将其颜色更改为灰色),
所以该方法会自动插入字符串
结论是 add/del 方法在执行时将 added/deleated 行更改为被选中
我试过什么:
add/del 行方法与两个按钮连接

 self.addrow_button.clicked.connect(
            lambda: self.datamodel.insertRows(-1, 1))
        self.deleaterow_button.clicked.connect(
            lambda: self.datamodel.removeRows(-1, 1))

所以我将它们连接到 selectionModel().clearSelection()) 以在某行获得 added/deleated

时清除该行的选择
self.addrow_button.clicked.connect(lambda: self.mytable_view.selectionModel().clearSelection())
        self.deleaterow_button.clicked.connect(lambda: self.mytable_view.selectionModel().clearSelection())

但这只会删除单元格的灰色---> 单元格仍处于选中状态,行为继续

有没有办法在执行 adding/deleating 行方法时禁止选择 above/below 行?


代码示例



"""
Testing Template for throw away experiment

"""


import sys
import os
import re

from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg



class DataModel(qtc.QAbstractTableModel):



    def __init__(self, input_data=None):
        super().__init__()

        self.input_data = input_data or [[None], [None], [None], [None], [None]]


    def data(self, index, role):

        if role == qtc.Qt.DisplayRole:
            try:
                text = self.input_data[index.row()][index.column()]
                # self.scaledatachanged_signal.emit() dont need it
            except IndexError:
                text = None

            return text

    def rowCount(self, index=qtc.QModelIndex()):
        return 0 if index.isValid() else len(self.input_data)


    def columnCount(self, index):
        return len(self.input_data[0])

    def headerData(self, section, orientation, role):
        if role == qtc.Qt.DisplayRole:

            if orientation == qtc.Qt.Vertical:
                return "row  " + str(section + 1)



    def flags(self, index):
        return qtc.Qt.ItemIsEditable | qtc.Qt.ItemIsSelectable | qtc.Qt.ItemIsEnabled

    def setData(self, index, value, role=qtc.Qt.EditRole):

        if role == qtc.Qt.EditRole:  # The data in a form suitable for editing in an editor. returns string
            try:
                row = index.row()
                column = index.column()

                # filter floats and digits and comma stuff

                pattern = '^[\d]+(?:[,.][\d]+)?$'  # execepts "," and "."

                if re.fullmatch(pattern, value, flags=0):
                    pattern = '^.*[,].*$'

                    if re.fullmatch(pattern, value, flags=0):

                        value = value.replace(',', '.')

                        self.input_data[row][column] = float(value)

                        print(type(value))

                    else:
                        self.input_data[row][column] = float(value)  # float

                        print(type(value))
                else:
                    pass

                return True

            except ValueError:
                return False

    def insertRows(self, position, rows, parent=qtc.QModelIndex()):
        position = (position + self.rowCount()) if position < 0 else position
        start = position
        end = position + rows - 1
        if end <= 8:
            self.beginInsertRows(parent, start, end)
            self.input_data.append([None])
            self.endInsertRows()
            return True
        else:
            return False

    def removeRows(self, position, rows, parent=qtc.QModelIndex()):
        position = (position + self.rowCount()) if position < 0 else position

        start = position

        end = position + rows - 1
        if end >= 1:
            self.beginRemoveRows(parent, start, end)
            del self.input_data[start:end + 1]
            self.endRemoveRows()
            return True
        else:
            return False

class MainWindow(qtw.QWidget):
    def __init__(self):
        super().__init__()



        self.mytable_view = qtw.QTableView()

        self.mytable_view.setSelectionMode(qtw.QAbstractItemView.SingleSelection)


        self.datamodel = DataModel()
        self.mytable_view.setModel(self.datamodel)

        # widget
        self.addrow_button = qtw.QPushButton("add row")
        self.deleaterow_button = qtw.QPushButton("deleate row")


    # set the layout
        layout = qtw.QVBoxLayout()
        layout.addWidget(self.mytable_view)
        layout.addWidget(self.addrow_button)
        layout.addWidget(self.deleaterow_button)

        self.setLayout(layout)


    # -------------------------------- #
        self.addrow_button.clicked.connect(
            lambda: self.datamodel.insertRows(-1, 1))
        self.deleaterow_button.clicked.connect(
            lambda: self.datamodel.removeRows(-1, 1))

        self.mytable_view.selectionModel().selectionChanged.connect(self.insert_data)


        self.addrow_button.clicked.connect(lambda: self.mytable_view.selectionModel().clearSelection())
        self.deleaterow_button.clicked.connect(lambda: self.mytable_view.selectionModel().clearSelection())



    def insert_data(self):

        x = self.mytable_view.selectionModel().currentIndex().row()
        y = self.mytable_view.selectionModel().currentIndex().column()


        self.datamodel.input_data[x][y] = "insert this string if cell is selected"
        self.datamodel.layoutChanged.emit()
        self.mytable_view.selectionModel().clearSelection()




if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)

    main = MainWindow()
    main.show()

    sys.exit(app.exec_())





每当删除 当前索引 的项目时,总是会自动 select 编辑前一个项目。请注意,当前索引无法匹配项目 selection:如果您 select 一个索引然后清除 selection,该索引仍将是当前索引。

最简单的解决方案是将当前索引设置为无效索引,方法是使用 QModelIndex 的新实例(这是一个无效索引)并在 之前 删除行。

        # ...
        self.deleaterow_button.clicked.connect(self.delete_row)
        # ...

    def delete_row(self):
        self.mytable_view.setCurrentIndex(qtc.QModelIndex())
        self.datamodel.removeRows(-1, 1)