Python 如何以编程方式编辑QabStretctTableModel?

Python 如何以编程方式编辑QabStretctTableModel?,python,qt,pyqt5,pyside2,Python,Qt,Pyqt5,Pyside2,注意:我不相信这是的副本,因为我不想插入新行。我想编辑表格数据 我已经更改了下面的代码。该表在标题为“2”和“3”的列中保存整数。当更改QSpinBox的值时,我希望表中的数字以编程方式乘以QSpinBox中的值 问题:如何通过编程将这些列中的值乘以spinbox乘数值 注意:如果UI不存在,模型仍然需要工作(没有这个乘数特性)。意思我认为spinbox必须启动模型数据编辑 我是否应该执行self.proxy\u mode.setData(),如果是,如何执行?我就是这样解决的。不完全确定是否

注意:我不相信这是的副本,因为我不想插入新行。我想编辑表格数据

我已经更改了下面的代码。该表在标题为“2”和“3”的列中保存整数。当更改QSpinBox的值时,我希望表中的数字以编程方式乘以QSpinBox中的值

问题:如何通过编程将这些列中的值乘以spinbox乘数值

注意:如果UI不存在,模型仍然需要工作(没有这个乘数特性)。意思我认为spinbox必须启动模型数据编辑


我是否应该执行self.proxy\u mode.setData(),如果是,如何执行?

我就是这样解决的。不完全确定是否通过mapFromSource获取索引,但它可以工作

import sys
import copy

try:
    from PySide2 import QtWidgets
except ImportError:
    from PyQt5 import QtWidgets

try:
    from PySide2 import QtCore
except ImportError:
    from PyQt5 import QtCore


class MyTableModel(QtCore.QAbstractTableModel):
    def __init__(self, table_data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self.table_data = table_data

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

    def columnCount(self, parent):
        return len(self.table_data[0])

    def flags(self, index):
        original_flags = super(MyTableModel, self).flags(index)
        return original_flags | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            item = index.internalPointer()
            if item is not None:
                print(item)
            value = self.table_data[row][column]
            return value

    def setData(self, index, value, role=QtCore.Qt.EditRole):
        if role == QtCore.Qt.EditRole:
            row = index.row()
            column = index.column()
            self.table_data[row][column] = value
            self.dataChanged.emit(index, index)
            return True
        return QtCore.QAbstractTableModel.setData(self, index, value, role)


class Widget(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        QtWidgets.QWidget.__init__(self, *args, **kwargs)

        self.view = QtWidgets.QTableView()
        self.setLayout(QtWidgets.QVBoxLayout())
        self.layout().addWidget(self.view)

        table_data = [['HD', '1920', '1080', 'other', 'stuff', 'here'], ['lowres', '640', '480', 'other', 'stuff', 'here']]

        self._original_table_data = copy.deepcopy(table_data)

        self.proxy_model = QtCore.QSortFilterProxyModel()
        self.model = MyTableModel(table_data=table_data)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setDynamicSortFilter(True)
        self.view.setModel(self.proxy_model)
        self.proxy_model.dataChanged.connect(self.on_data_changed)

        self.view.setSortingEnabled(True)  # requires proxy model
        self.view.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.horizontalHeader().setSectionsMovable(True)

    def on_data_changed(self, _from, _to):
        model = _from.model() # proxy model
        model.blockSignals(True)
        for index in self.view.selectionModel().selectedIndexes():
            model.setData(index, _from.data())
        model.blockSignals(False)
        print('data was changed in table')

    def change_value(self, col, multiplier):
        print('Multiply the value (for all rows) in column %s with: %s' % (col, multiplier))

        index = self.proxy_model.mapFromSource(QtCore.QModelIndex())
        row_count = self.proxy_model.rowCount(index)

        for row in range(0, row_count):
            original_value = self._original_table_data[row][col]
            index = self.proxy_model.index(row, col)
            self.proxy_model.setData(index, int(original_value)*int(multiplier))



if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    m = QtWidgets.QWidget()
    w = Widget()
    q = QtWidgets.QLabel('Multiplier:')
    e = QtWidgets.QSpinBox()
    e.setValue(1)
    e.valueChanged.connect(lambda: w.change_value(col=1, multiplier=e.value()))
    e.valueChanged.connect(lambda: w.change_value(col=2, multiplier=e.value()))
    l = QtWidgets.QHBoxLayout()
    l.addWidget(w)
    l.addWidget(q)
    l.addWidget(e)
    m.setLayout(l)
    m.show()
    sys.exit(app.exec_())

您可以迭代给定列中的单元格,并为每个单元格调用
qabstractemmodel::setData()
。这可能类似于:@eyllansc的可能重复项我看不出这是一个重复项,因为该问题/答案描述了如何输入新行。@vahancho您能详细说明一下吗?我不明白如何在这里使用
setData
import sys
import copy

try:
    from PySide2 import QtWidgets
except ImportError:
    from PyQt5 import QtWidgets

try:
    from PySide2 import QtCore
except ImportError:
    from PyQt5 import QtCore


class MyTableModel(QtCore.QAbstractTableModel):
    def __init__(self, table_data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self.table_data = table_data

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

    def columnCount(self, parent):
        return len(self.table_data[0])

    def flags(self, index):
        original_flags = super(MyTableModel, self).flags(index)
        return original_flags | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            item = index.internalPointer()
            if item is not None:
                print(item)
            value = self.table_data[row][column]
            return value

    def setData(self, index, value, role=QtCore.Qt.EditRole):
        if role == QtCore.Qt.EditRole:
            row = index.row()
            column = index.column()
            self.table_data[row][column] = value
            self.dataChanged.emit(index, index)
            return True
        return QtCore.QAbstractTableModel.setData(self, index, value, role)


class Widget(QtWidgets.QWidget):
    def __init__(self, *args, **kwargs):
        QtWidgets.QWidget.__init__(self, *args, **kwargs)

        self.view = QtWidgets.QTableView()
        self.setLayout(QtWidgets.QVBoxLayout())
        self.layout().addWidget(self.view)

        table_data = [['HD', '1920', '1080', 'other', 'stuff', 'here'], ['lowres', '640', '480', 'other', 'stuff', 'here']]

        self._original_table_data = copy.deepcopy(table_data)

        self.proxy_model = QtCore.QSortFilterProxyModel()
        self.model = MyTableModel(table_data=table_data)
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.setDynamicSortFilter(True)
        self.view.setModel(self.proxy_model)
        self.proxy_model.dataChanged.connect(self.on_data_changed)

        self.view.setSortingEnabled(True)  # requires proxy model
        self.view.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.horizontalHeader().setSectionsMovable(True)

    def on_data_changed(self, _from, _to):
        model = _from.model() # proxy model
        model.blockSignals(True)
        for index in self.view.selectionModel().selectedIndexes():
            model.setData(index, _from.data())
        model.blockSignals(False)
        print('data was changed in table')

    def change_value(self, col, multiplier):
        print('Multiply the value (for all rows) in column %s with: %s' % (col, multiplier))

        index = self.proxy_model.mapFromSource(QtCore.QModelIndex())
        row_count = self.proxy_model.rowCount(index)

        for row in range(0, row_count):
            original_value = self._original_table_data[row][col]
            index = self.proxy_model.index(row, col)
            self.proxy_model.setData(index, int(original_value)*int(multiplier))



if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    m = QtWidgets.QWidget()
    w = Widget()
    q = QtWidgets.QLabel('Multiplier:')
    e = QtWidgets.QSpinBox()
    e.setValue(1)
    e.valueChanged.connect(lambda: w.change_value(col=1, multiplier=e.value()))
    e.valueChanged.connect(lambda: w.change_value(col=2, multiplier=e.value()))
    l = QtWidgets.QHBoxLayout()
    l.addWidget(w)
    l.addWidget(q)
    l.addWidget(e)
    m.setLayout(l)
    m.show()
    sys.exit(app.exec_())