Quando emitir o dataChanged de um QAbstractItemModel
No Qt, eu tenho uma subclasse de modeloQAbstractItemModel
- é uma árvore exibida em um QTreeView.
O modelo suporta várias formas de mudança que funcionam bem. Os dois de relevância são:
1) Alguns dados em um pequeno número de alterações de linhas relacionadas
2) Uma mudança de visualização significa que a maioria das linhas deve alterar sua formatação - em particular, elas têm uma mudança de realce de plano de fundo. SeusDisplayRole
os dados não mudam.
O design atual lida com ambos da mesma maneira: para cada linha que tenha alguma alteração, o modelo emitedataChanged(start_of_row_index,end_of_row_index)
. Eu emito o sinal para as duas linhas pai que mudam e para qualquer um dos filhos que mudaram.
No entanto, isso ocorre mal no caso 2, à medida que o modelo se torna grande: um número muito grande dedataChanged
sinais são emitidos.
Eu mudei o código para que no caso 2 o modelo emitedataChanged
somente para a linha (única) que é o pai da árvore inteira.
Isso ainda parece funcionar corretamente, mas não está de acordo com minha compreensão das responsabilidades do modelo. Mas suspeito que posso estar errado.
Talvez eu esteja entendendo mal odataChanged
sinal? Isso realmente faz com que a exibição atualize todos os filhos, assim como o intervalo especificado? Ou eu posso evitar de emitirdataChanged
quando não é oDisplayRole
isso está mudando?
Como Jan aponta, eu devo emitirdataChanged
quer para a maioria ou para todas as linhas no caso 2.
Meu código originalmente fez isso emitindodataChanged
para cada linha alterada, mas isso é muito caro - a visão demora muito para processar todos esses sinais.
Uma solução possível seria agregar odataChanged
sinal para quaisquer blocos contíguos de linhas alteradas, mas isto ainda não terá um bom desempenho quando, por exemplo, todas as outras linhas forem alteradas - ainda assim emitiria muitos sinais.
Idealmente, gostaria de dizer à visão para considerar todos os dados como potencialmente alterados (mas todos os índices ainda são válidos - o layout inalterado). Isso não parece ser possível com um único sinal.
Por causa de uma peculiaridade doQTreeView
classe, é possível (embora incorreto de acordo com a especificação) para emitir apenas umdataChanged(tl,br
) enquantotl != br
. Eu tive este trabalho e passou nos nossos testes, mas me deixou nervoso.
Eu tenho resolvido por agora em uma versão que atravessa a árvore e emite um únicodataChanged(tl,br)
para todos os pais (com tl, br abrangendo todos os filhos desse pai). Isso está de acordo com o modelo / protocolo de visualização e, para nossos modelos, ele normalmente reduz o número de sinais em cerca de um fator de 10.
Não parece ideal no entanto. Alguma outra sugestão alguém?