Qt 3.2 QCanvas Probleme mit Performance mit Hintergrundbild

Alles rund um die Programmierung mit Qt
Antworten
Christoph
Beiträge: 24
Registriert: 29. März 2005 15:22
Wohnort: Muenchen

Qt 3.2 QCanvas Probleme mit Performance mit Hintergrundbild

Beitrag von Christoph »

Hallo,

ich arbeite mit Qt 3.2 und habe in meiner Anwendung ein relativ grosses QCanvas-Objekt (8192x8192) erzeugt und benutze
eine von QCanvasView abgeleitete Klasse, um es anzuzeigen.

Der Canvas selbst dient zur Visualisierung von SMD-Bauelementen auf einer
Leiterplatte.
Die aus QCanvasPolygonen dargestellten, masstäblich mit allen Anschluessen
versehenen Bauelemente lassen sich so einfach markieren, mit der Maus verschieben, drehen,
usw.
Um nun die Richtigkeit der einzelnen Bauelemente-Positionen
und Bauelement-Typen zu verifizieren ist es hilfreich, ein Bild der Leiterplatte
(noch ohne Bauelemente) als Hintergrund hinter die Darstellung der Bauelemente einzblenden.
Ich möchte also ein Bild als Hintergrund verwenden um z.B. Bauelemente auf dem Canvas mit
der Maus an die richtige Position zu schieben.
Da ich die Bauelemente wegen der Detailtreue ihrer Anschluesse nicht beliebig klein machen
kann, bin ich also gezwungen dieses Hintergrundbild zunächst auf den Masstab der Bauelemente
zu bringen. (Um ein Bauelement mit der Maus auf seine Zielposition zu verschieben,
wird man sich immer an den Anschussbeinchen orientieren,
denn um die geht es ja letztlich)
Dazu muß ich eine eingescannte Leiterplatte etwa mit dem Faktor 5 skalieren.
(Ein Bild von z.B. 1024 x 768 wird bei mir also auf ca. 5120 x 3840 vergroessert,
um masstäblich mit den Bauelementen zusammenzupassen.
Da die Größen der Bauelemente sehr stark
schwanken ist die Zoombarkeit des QCanvasView-Objektes elementar.
Ich realisiere das über die Funktion QCanvasView setWorldMatrix(QWMatrix).
Das funktioniert auch alles toll, wenn man den Hintergrund des Canvas
selbst nur mit weißer Farbe fuellt.
Die Probleme beginnen mit dem Hintergrundbild, denn da wird bei meinen
bisherigen Loesungsversuchen die Geschichte einfach zu langsam und auch der Speicherbedarf steigt ins astronomische.


Ich habe fuer den Hintergrund bis dato folgende Varianten erprobt:

Eine QPixmap mit der Groesse des QCanvas erzeugen, weiss fuellen und anschliessend
das schon auf erforderliche Groesse gezoomte Hintergrundbild mit
bitBlt(QPixmap dst,0,0, QPixmap src) in diese Pixmap hineinkopieren.
Ich machte die Hintergrund-Pixmap deshalb so gross, weil wenn die Pixmap kleiner
als der Canvas selbst ist, wird die Pixmap in den Canvas "hineingekachelt" wie oft
sie eben passt. Ich hätte dann also die Abbildung der Leiterplatte mehrmals im Canvas,
was ich nicht möchte.

Eine QCanvasPixmap mit der Groesse des auf erforderliche Groesse gezoomten
Hintergrundbildes erzeugen, diese QCanvasPixmap als einziges Bild in eine
QCanvasPixmapArray kopieren und diese dann als QCanvasSprite-Objekt anzeigen lassen

Das funktioniert prinzipiell das alles, keine Frage,
und die Performance sinkt auf ein zwar noch akzeptables Mass ab,
sobald der Zoomfaktor des QCanvasView ungleich 1.00 ist,
wenn aber der Zoom-Faktor sehr hoch wird ( z.B. ca. 5.00 ),
dann wird der Bildaufbau sehr zäh, es kann durchaus 5 Sekunden dauern,
bis sich z.B. eine Verschiebung eines Bauelementes am Bildschirm abzeichnet.

Ich bin weiterhin auf eine interessante Funktion gestossen:

QCanvas setTiles(QPixmap bild,
int anzahl_in_x,
int anzahl_in_y,
int groesse_in_x,
int groesse_in_y)

ich habe eingentlich gedacht, daß man damit eine QPixmap
praktisch in eine Matrix aus Kacheln zerteilen kann, bei einem Paint-Event koennten dann
immer nur die betroffenen Kacheln neu gezeichnet werden, aber die Funktion liefert
immer nur die linke obere Ecke der QPixmap in jeder Kachel, das ist natuerlich auch nicht
das wahre. 3Allerdings, die Performance waere in allen Zoombereichen mindestens akzeptabel,
wenn nicht besser.

Ich denke, daß das ein Ansatz sein koennte, die Pixmap in Kaheln zu zerteilen und in das
QCanvas-Objekt einzublenden, aber ich habe keine Idee, wie man das hinkriegt.

Wer weiß Rat ?

Vielen Dank.
Antworten