how can i achieve to update multiple rows in a qtableview

安稳与你 提交于 2019-12-08 07:28:52

问题


I have a customized qtablemodel and a qtableview. I would like to add a feature that the user can select multiple rows and by changing one of the values within this rows. He would actually change this value in all rows. e.g. the user could change the name of all persons in the table to alice when he selected the whole table.

Can you help me to achieve this?

I do not understand how i can trigger the setData of the model a multiple times for different rows. Or can you tell me which signal the qtableview sends to the model before the setData function within the model is called?

Thanks a lot in advance donny


回答1:


I might have a slightly more straight-forward solution the problem of editing all selected values in the same column at the same time. Instead of overriding QTableView::edit(), it's easier to override QTableView::commitData(editor), which is called after the user has submitted their edit.

In short: When the user submits their edits, iterate through all other selected rows and apply the exact same value change to cells with the same column as the edited cell.

Here's a Python example, translation to C++ should be easy (add semicolons everywhere, replace self with this):

class ImageTableView(QtGui.QTableView):
    def commitData(self, editor):
        # call parent commitData first
        super(ImageTableView, self).commitData(editor)

        # self.currentIndex() is the QModelIndex of the cell just edited
        theModel = self.currentIndex().model()
        # get the value that the user just submitted
        value = theModel.data(self.currentIndex(), QtCore.Qt.EditRole)

        curRow, curCol = self.currentIndex().row(), self.currentIndex().column()

        # selection is a list of QItemSelectionRange instances
        for isr in self.selectionModel().selection():
            rows = range(isr.top(), isr.bottom()+1)
            for row in rows:
                if row != curRow:
                    # row,curCol is also in the selection. make an index:
                    idx = theModel.index(row, curCol)
                    # so we can apply the same value change
                    theModel.setData(idx, value, QtCore.Qt.EditRole)



回答2:


Can you not get a QModelList from QTableView::selectedIndexes(), and iterate through that?




回答3:


Depending on you have implemented your model/view, you might be able to connect the QAbstractItemModel::dataChanged signal to a slot that cycles through every selected item. Not every version of setData emits this signal, but you can opt to do so if you override it.

Take a look at the source code for QTableWidgetItem::setData for an example. It's in the qtablewidget.cpp file.


Edit: Alternatively, you could key in on either the delegate's closeEditor or commitData signals to intercept the editor's value and apply it to every selected item. You would have to subclass QTableView to accomplish this, so here's a little sample code to get you started inspired from here:

class MyTableView : public QTableView {
    Q_OBJECT
public:
    explicit MyTableView(QWidget* parent = 0) : QTableView(parent) {
        connect(this->itemDelegate(), SIGNAL(closeEditor(QWidget*)),
                this, SLOT(editMultipleItems(QWidget*)));
    }

public slots:
    void editMultipleItems(QWidget* editor) {
        QLineEdit* myeditor = qobject_cast<QLineEdit*>(editor);     //recast to whatever widget was actually used
        if(myeditor != 0) {
            foreach(const QModelIndex& index, this->selectionModel()->selectedIndexes()) {
                QVariant v(myeditor->text());
                model()->setData(index, v, Qt::EditRole);
            }
        }
    }
};

As a third option, you can override QStyledItemDelegate with a special case for multiple selections, then customize setModelData() to edit every selected item instead of just the one that received the edit trigger.

You could also combine the second and third options by having the trivially subclassed QStyleItemDelegate::setModelData() emit a signal connected to your MyTableView's multiItemEdit slot with the new value.



来源:https://stackoverflow.com/questions/14586715/how-can-i-achieve-to-update-multiple-rows-in-a-qtableview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!