как отключить поведение выбора строки при добавлении / удалении строки в QTableView - PullRequest
0 голосов
/ 17 июня 2020

У меня есть подкласс QAbstractTableModel с методом вставки / удаления строк

в главном окне У меня есть методы insert_data, которые вставляют строку, когда ячейка в данный момент выбрана (я включил одиночный выбор )
Вот поведение, которое я хочу изменить:
, когда я вставляю значение в ячейку с помощью метода setData подкласса QAbstractTableModel или с помощью insert_data
и удаляю эту строку - -> строка выше выбирается (строка меняет свой цвет на серый),
, поэтому метод автоматически вставляет строку
, вывод заключается в том, что методы 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()), чтобы очистить выбор этой строки при добавлении строки / удалено

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

, но при этом удаляется только серый цвет ячейки ---> ячейка по-прежнему выбрана, поведение продолжается

есть ли способ отключить, что abo При выполнении метода добавления / удаления строки выбирается строка ve / ниже?


пример кода



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





1 Ответ

1 голос
/ 17 июня 2020

Каждый раз, когда удаляется элемент, имеющий текущий индекс , всегда автоматически выбирается предыдущий. Обратите внимание, что текущий индекс не может соответствовать выбранному элементу: если вы выберете индекс и затем очистите выбор, этот индекс все равно будет текущим индексом.

Самое простое решение - установить для текущего индекса недопустимый один b для использования нового экземпляра QModelIndex (который является недопустимым индексом) и перед удалением строки.

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

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