我有一个定制的 qtablemodel 和一个 qtableview。我想添加一个功能,用户可以选择多行并通过更改此行中的一个值。他实际上会在所有行中更改此值。例如,当他选择整个表格时,用户可以将表格中所有人的名字更改为 alice。
你能帮我实现这个目标吗?
我不明白如何为不同的行多次触发模型的 setData。或者你能告诉我在调用模型中的 setData 函数之前 qtableview 向模型发送了哪个信号吗?
提前非常感谢唐尼
我有一个定制的 qtablemodel 和一个 qtableview。我想添加一个功能,用户可以选择多行并通过更改此行中的一个值。他实际上会在所有行中更改此值。例如,当他选择整个表格时,用户可以将表格中所有人的名字更改为 alice。
你能帮我实现这个目标吗?
我不明白如何为不同的行多次触发模型的 setData。或者你能告诉我在调用模型中的 setData 函数之前 qtableview 向模型发送了哪个信号吗?
提前非常感谢唐尼
对于同时编辑同一列中所有选定值的问题,我可能有一个稍微更直接的解决方案。与重写 QTableView::edit() 不同,重写 QTableView::commitData(editor) 更容易,它在用户提交编辑后调用。
简而言之:当用户提交他们的编辑时,遍历所有其他选定的行并将完全相同的值更改应用于与编辑单元格具有相同列的单元格。
这是一个 Python 示例,翻译成 C++ 应该很容易(在任何地方添加分号,替换self
为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)
根据您实现的模型/视图,您可能能够将QAbstractItemModel::dataChanged
信号连接到循环遍历每个选定项目的插槽。并非每个版本的 setData 都会发出此信号,但如果您覆盖它,您可以选择这样做。
以 QTableWidgetItem::setData 的源代码为例。它在 qtablewidget.cpp 文件中。
编辑:或者,您可以键入委托的closeEditor或commitData信号以拦截编辑器的值并将其应用于每个选定的项目。您必须将 QTableView 子类化才能完成此操作,所以这里有一些示例代码可以让您从这里开始获得灵感:
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);
}
}
}
};
作为第三个选项,您可以使用特殊情况覆盖QStyledItemDelegate以进行多项选择,然后自定义 setModelData() 以编辑每个选定的项目,而不仅仅是接收编辑触发器的项目。
您还可以通过让平凡的子类 QStyleItemDelegate::setModelData() 使用新值发出连接到 MyTableView 的 multiItemEdit 插槽的信号来组合第二个和第三个选项。
你不能从 QTableView::selectedIndexes() 得到一个 QModelList,然后遍历它吗?