简体   繁体   English

排序QtTableModel - QTableView没有更新

[英]Sorting QtTableModel - QTableView doesn't get updated

I implemented a custom QAbstractTableModel and I'm using a std::vector for my data objects. 我实现了一个自定义的QAbstractTableModel ,我正在为我的数据对象使用std::vector

Now I wanted to implement the sort() method, to get my table sorted by column. 现在我想实现sort()方法,以便按列对表进行排序。 That's basically what I do: 这基本上就是我做的事情:

void SBStateTableModel::sort (int column, Qt::SortOrder order)
{
emit layoutAboutToBeChanged();

switch (column)
{
case Address:
    if (order == Qt::DescendingOrder)
        std::sort(states.begin(), states.end(), addr_comp_desc);
    else
        std::sort(states.begin(), states.end(), addr_comp_asc);

default:
    return;
}

emit layoutChanged();
}

But emitting layoutChanged() alone doesn't redraw the view. 但是单独发出layoutChanged()不会重绘视图。 When mark a row and cycle through them, they get updated as they are being highlighted. 标记行并循环显示行时,它们会在突出显示时更新。

The documentation also speaks about updating the persistent indexes. 该文档还谈到了更新持久性索引。 Some people on here have suggested, that this is in fact not necessary. 这里的一些人建议,这实际上没有必要。 I'm not even sure how to go about it. 我甚至不确定如何去做。 Getting the list with persistentIndexList() and then I have to sort it. 使用persistentIndexList()获取列表然后我必须对其进行排序。 But std::sort is not a stable sort. 但是std::sort不是一个稳定的类型。 I'm not sure how to match the persistent indices with my vector indices. 我不确定如何将持久性索引与我的矢量索引相匹配。

EDIT: There was just a "break" missing in the 'case'! 编辑:'案例'中只有一个“休息”缺失! So the function would return before emitting the layoutChanged signal. 因此函数将在发出layoutChanged信号之前返回。

D'oh! D'哦!

I was ready to dig into the Qt Source Code. 我准备深入研究Qt源代码。 But as I single stepped through my code, I saw the cursor jumping to the return statement in the 'default' case. 但是当我单步执行我的代码时,我看到光标跳转到'default'情况下的return语句。

I had just forgotten to add a 'break' to my switch-case! 我忘记在我的开关盒中添加一个“休息”! It was just a simple fall-through error :(( It works now perfectly fine with "layoutChanged". 这只是一个简单的掉头错误:((现在它对“layoutChanged”完全没问题。)

I just did this. 我刚刚这样做了 First, you have to connect the header signal to the sort method you have created. 首先,您必须将标头信号连接到您创建的排序方法。 This is a Python sample so you'll need to adapt it to C++: 这是一个Python示例,因此您需要将其调整为C ++:

model = SBStateTableModel()
table = QtGui.QTableView()
table.setModel(model)

table.setSortingEnabled(True)

When you sort, the entire view will change - or at least most of the view will change. 排序时,整个视图将发生变化 - 或者至少大部分视图都会发生变化。 So emitting the modelReset signal will cause the view to change. 因此,发出modelReset信号将导致视图发生变化。 Model reset is one of the most inefficient signals to call, because it causes the entire view to be redrawn. 模型重置是要调用的效率最低的信号之一,因为它会导致整个视图被重绘。 However, most of the view will change anyway on a sort. 但是,大多数视图无论如何都会改变。

emit modelReset();

You could also emit the dataChanged signal, indicating that all of the data has changed. 您还可以发出dataChanged信号,指示所有数据都已更改。 The dataChanged signal may be faster. dataChanged信号可能更快。

Python: 蟒蛇:

self.dataChanged.emit(self.index(0, 0), self.index(self.rowCount()-1, self.columnCount()-1))

C++: C ++:

(emitting a dataChanged signal, in a subclass of QTableView) (在QTableView的子类中发出dataChanged信号)

auto m = model();
emit dataChanged (m->index(0, 0), m->index(m->rowCount()-1, m->columnCount()-1));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM