Перетащите всю строку в QAbstractTableModel PyQt5 - PullRequest
0 голосов
/ 30 мая 2020

У меня есть простой пример QAbstractTableModel. Цель состоит в том, чтобы перетащить всю строку в таблице. Я повторно реализовал необходимые функции, но понятия не имею, как повторно реализовать функции MIME (я вызвал их в конце своего класса, но оставил их нетронутыми). Не могли бы вы помочь мне с этим примером?

from PyQt5 import QtCore, QtGui, QtWidgets
import sys

    class Mainwindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()

        self.table = QtWidgets.QTableView()
        self.setCentralWidget(self.table)

        headers = [None, 'Matreial', 'γ, kg/m3', 'λa', 'λb']

        data = [
            [1, 'Blocks γ=500 GOST 31359-2007', 500, 0.18, 0.22],
            [2, 'Blocks γ=600 GOST 31359-2008', 600, 0.25, 0.27],
            [3, 'Insulation', '80-125', 0.041, 0.042]
            ]

        model = Materials(data, headers)
        self.table.setModel(model)

        self.table.setSelectionBehavior(self.table.SelectRows)
        self.table.setSelectionMode(self.table.SingleSelection)
        self.table.setDragDropMode(self.table.InternalMove)
        self.table.setDropIndicatorShown(True)
        self.table.setDragEnabled(True)
        self.table.setAcceptDrops(True)


class Materials(QtCore.QAbstractTableModel):

    def __init__(self, materials = [[]], headers = [], parent = None):
        super(Materials, self).__init__()
        self.materials = materials
        self.headers = headers

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

    def columnCount(self, parent):
        return len(self.headers)

    def data(self, index, role):

        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.materials[row][column]
            return value

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

        if role == QtCore.Qt.EditRole:
            row = index.row()
            column = index.column()
            text = str(value)
            if type(text)==str:
                self.materials[row][column] = text
                self.dataChanged.emit(index, index)
                return True
        return False

    def headerData(self, section, orientation, role):

        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self.headers[section]

    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled

    def insertRows(self, position, rows, parent = QtCore.QModelIndex()):
        self.beginInsertRows(parent, position, position + rows - 1)

        for i in range(rows):

            defaultValues = ['' for i in range(self.columnCount(None))]
            self.materials.insert(position, defaultValues)

        self.endInsertRows()
        return True

    def removeRows(self, position, rows, parent = QtCore.QModelIndex()):
        self.beginRemoveRows(parent, position, position + rows - 1)

        for i in range(rows):
            value = self.materials[position]
            self.materials.remove(value)

        self.endRemoveRows()
        return True


    def supportedDropActions(self):
        return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction

    def supportedDragActions(self):
        return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction

    def mimeTypes(self):
        return super().mimeTypes()

    def mimeData(self, indexes):
        return super().mimeData(indexes)

    def dropMimeData(self, data, action, row, col, parent):
         return super().dropMimeData(data, action, row, col, parent)



if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    application = Mainwindow()
    application.show()


    sys.exit(app.exec())

1 Ответ

0 голосов
/ 31 мая 2020

Я разобрался: повторно реализовал mimeTypes, mimeData, dropMimeData. Также изменил insertRows. Код dropMimeData выглядит немного некрасиво - буду рад, если появятся предложения, как его улучшить.

В любом случае, жду комментариев!

from PyQt5 import QtCore, QtGui, QtWidgets
import sys

class Mainwindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()

        self.table = QtWidgets.QTableView()
        self.setCentralWidget(self.table)

        headers = [None, 'Matreial', 'γ, kg/m3', 'λa', 'λb']

        data = [
            [1, 'Blocks γ=500 GOST 31359-2007', 500, 0.18, 0.22],
            [2, 'Blocks γ=600 GOST 31359-2008', 600, 0.25, 0.27],
            [3, 'Insulation', '80-125', 0.041, 0.042]
            ]

        self.model = Materials(data, headers)
        self.table.setModel(self.model)

        self.table.setSelectionBehavior(self.table.SelectRows)
        self.table.setSelectionMode(self.table.SingleSelection)
        self.table.setDragDropMode(self.table.InternalMove)
        self.table.setDropIndicatorShown(True)
        self.table.setDragEnabled(True)
        self.table.setAcceptDrops(True)





class Materials(QtCore.QAbstractTableModel):

    def __init__(self, materials = [[]], headers = [], parent = None):
        super(Materials, self).__init__()
        self.materials = materials
        self.headers = headers

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

    def columnCount(self, parent):
        return len(self.headers)

    def data(self, index, role):

        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            value = self.materials[row][column]
            return value

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

        if role == QtCore.Qt.EditRole:
            row = index.row()
            column = index.column()
            text = str(value)
            if type(text)==str:
                self.materials[row][column] = text
                self.dataChanged.emit(index, index)
                return True
        return False

    def headerData(self, section, orientation, role):

        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self.headers[section]

    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled

    def insertRows(self, value, position, rows, parent = QtCore.QModelIndex()):  ####add value
        self.beginInsertRows(parent, position, position + rows - 1)

        for i in range(rows):
            self.materials.insert(position, value)       ####change here

        self.endInsertRows()
        return True

    def removeRows(self, position, rows, parent = QtCore.QModelIndex()):
        self.beginRemoveRows(parent, position, position + rows - 1)

        for i in range(rows):
            item = self.materials[position]
            self.materials.remove(item)

        self.endRemoveRows()
        return True


    def supportedDropActions(self):
        return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction

    def supportedDragActions(self):
        return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction


    def mimeTypes(self):
        return ['text']

    def mimeData(self, indexes):
        mimedata = QtCore.QMimeData()
        list_1 = []
        for i in indexes:
            list_1 += [str(i.data())]

        b = bytearray(','.join(list_1).encode('utf-8'))
        mimedata.setData('text', b)

        return mimedata

    def dropMimeData(self, mimedata, action, row, col, parent):

        drop_data = mimedata.data('text').split(',')
        item_list = [b.data().decode('utf-8') for b in drop_data]


        new_list = []
        for item in item_list:
            try:
                new_list += [int(item)]
            except ValueError:
                new_list += [item]
        final_list = []
        for item in new_list:
            if type(item) == int:
                final_list += [item]
            else:
                try:
                    final_list += [float(item)]
                except ValueError:
                    final_list += [item]


        if final_list in self.materials:
             position = self.materials.index(final_list)

        self.removeRows(position, 1)
        self.insertRows(final_list, parent.row(), 1)

        return True



if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    application = Mainwindow()
    application.show()


    sys.exit(app.exec())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...