2017-09-01 2 views
0

Je crée une application qui trace les données de mesure à l'aide de la bibliothèque QtCharts. Quelques choses importantes qui devraient être mentionnées sont:Comment forcer QChartView à ne peindre qu'une partie de lui-même

  1. J'ai affaire à des séries temporelles.

  2. Les données de mesure sont obtenues hors ligne, ce qui signifie qu'elles ont déjà été obtenues. Mon programme le lit simplement à partir du fichier et l'affiche.

  3. Je travaille avec une boucle for qui prend les points de données sous forme de blocs d'une taille fixe (disons 10000) et les ajoute à la série de dispersion. De cette façon, les données sont "rejouées" et l'utilisateur peut voir la progression des données de mesure à de nombreux points de temps intermédiaires et pas seulement après que tous les points de données ont été tracés.

  4. Je travaille avec beaucoup de points de données, de l'ordre de millions.

A chaque itération de la boucle un nouveau QScatterSeries est créé, les points de données sont annexés, la série de points est ajoutée au diagramme et la vue graphique est repeint. Au début, c'est assez rapide, mais au fur et à mesure que le temps avance, le nombre de points à peindre augmente et le processus de peinture devient de plus en plus lent. Je sais pertinemment que je peux réimplémenter le paintEvent de la classe de vue de diagramme pour l'amener à redessiner seulement une partie de lui-même. Je pense que je peux le rendre plus rapide en mettant à jour seulement les parties qui ont de nouveaux points de données. Je vais juste calculer les coordonnées de la région où de nouveaux points de données ont été ajoutés et utiliser paintEvent. Mais comment puis-je le faire? J'ai essayé d'utiliser la méthode setClipRect() de QPainter, mais je n'ai pas pu le faire. Merci d'avance.

Répondre

0

QGraphicsView/QGraphicsItem ne pas l'implémenter. Ils ne le sont pas parce que c'est malheureusement généralement impossible: les éléments affichés (par exemple des séries) sont mis à l'échelle et anti-aliasés. Autrefois, lorsque tout était affiché dans les unités de l'appareil, et qu'il était dessiné directement sur la fenêtre, faire des mises à jour partielles avait du sens: vous utilisiez d'abord un blit rapide pour décaler le tracé existant, puis dessiner de nouveaux points. Hélas, dans toute visionneuse de scènes non triviale, la relation entre les unités de périphérique horizontal (widget) et les unités d'élément (diagramme/série) n'est pas 1: 1, il n'y a donc pas de moyen général de faire défiler les données dans le périphérique unités et ont encore du sens dans les unités de carte. Il existe une solution de contournement: faites défiler le nombre d'unités de périphérique supérieur au nombre nécessaire (arrondi au nombre supérieur), puis calculez à nouveau le résultat obtenu en unités de graphique, puis compensez le graphique par un nombre (par ex. déplacez la plage de l'axe X en conséquence).

Cela pourrait être implémenté avec une relative facilité dans les sources du système QGraphicsView, à mesure que le graphique se construit dessus. Il n'y a aucun moyen de "verrouiller ceci" de l'extérieur - vous devez ajouter un tel support directement à l'infrastructure QGraphicsView et QGraphicsItem, puis avoir le QChartView en tirer profit. Si vous n'avez pas l'habitude de construire votre propre Qt, vous pouvez bien sûr copier les classes nécessaires dans votre base de code et les renommer.

+0

Tout d'abord, merci pour la réponse. Il y a peut-être des choses que je ne peux pas dire très clairement. Tout d'abord, puisque tous les points de données sont disponibles au début, je vais d'abord trouver les min et max de ces points pour les deux coordonnées et ensuite définir les plages des axes à ces valeurs. De cette façon, il n'y aura pas besoin de redimensionner les axes.En outre, il ne sera pas nécessaire de redessiner les points qui figuraient déjà sur le graphique, car leurs positions ne changeront pas. Les nouveaux points de données seront placés sur les régions précédemment vides. Donc, je veux juste donner l'emplacement de cette région –

+0

C'est faisable mais nécessite encore des mods au code Qt. –