Seite 1 von 3
boundingRect für graphicItems -> abhängig von zoom
Verfasst: 17. September 2007 18:04
von q-tee
hallo,
die paint-funktion eines graphicItems soll ein rechteck mit fester (fixRect)und eins mit variabler(varRect) breite zeichnen. dazu wird die breite von fixRect durch den streckfaktor in x-richtung geteilt. das problem ist nun aber, dass das boundingRect nicht korrekt berechnet wird (sollte sich ja je nach zoom-faktor des views unterscheiden) und die hover-effekte nicht korrekt sind. so tauchen grafikfehler auf...
ist das irgendwie möglich in der boundingRect-funktion die breite richtig zu berechnen oder gibt es eine bessere möglichkeit, wenn die beiden rechtecke (aus performance-gründen) in einem graphicItem bleiben sollen?
Code: Alles auswählen
class Rect : public QGraphicsItem
{
public:
Rect(height, width);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget);
}
Code: Alles auswählen
void Rect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
float xScale = option->matrix.m11();
float fixRectWidth = width/xScale;
float varRectWidth = width;
QRectF fixRect = QRectF (- fixRectWidth, 0, fixRectWidth, height);
QRectF varRect = QRectF (0 , 0, varRectWidth, height);
}
Code: Alles auswählen
QRectF Rect::boundingRect() const
{
return QRectF(-fixRectWidth, 0, fixRectWidth + varRectWidth, height);
}
x- und breite-attribute müssten denke ich vom streckfaktor abhängig sein. aber wie komm ich da dran?
danke schonmal
Verfasst: 18. September 2007 09:46
von q-tee
ich mal euch mal auf wie das aussehen soll. is vielleicht nich leicht zu verstehen sonst.
stark gezoomt:
-> scale = 5
breite der rechtecke auf dem bildschirm (in pixel): fix = 100, var = 500
Code: Alles auswählen
--------------------------------------------------------------------------------
| fix | var |
--------------------------------------------------------------------------------
wenig gezoomt:
-> scale = 1.5
breite der rechtecke auf dem bildschirm (in pixel): fix = 100, var = 150
Code: Alles auswählen
---------------------------------
| fix | var |
---------------------------------
Verfasst: 25. September 2007 16:00
von CaptnChaos
hast du das geschafft?
Verfasst: 28. September 2007 14:26
von q-tee
ehrlich gesagt nich. hab es jetzt so gelöst, dass das fixRect doch ein child von varRect ist, und ItemIgnoresTransformations gesetzt.
nur soll das teil dummerweise in y-richtung doch mitskaliert werden (also nur eine feste breite haben). in der paint-funktion habe ich das hinbekommen
Code: Alles auswählen
void fixRect::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
float yScale = option->matrix.m22();
QRectF rect = QRectF(0, 0, width, height * yScale);
painter->drawRect(rect);
}
aber das bounding-rect wird natürlich in y-richtung nich richtig berechnet.
hast du noch ne idee?
Verfasst: 28. September 2007 15:01
von CaptnChaos
du könntest die boundingRect() funktion neu implementieren und selbst ein boundingRect berechnen. So hab ich es jedenfalls mal gemacht.
Dürfte normal kein Problem sein, da boundingRect() virtual ist.
Gruß Markus
Verfasst: 28. September 2007 15:34
von q-tee
klar aber um da wieder den aktuellen zoom-faktor rauszukriegen müsste ich wieder alle views durchgehen, schauen auf welchem grad der mauszeiger is, das ding speichern. so wie
*hier*
und da hab ich angst um meine performane da es 2 * 8000 mal gemacht werden müsste.
Verfasst: 28. September 2007 15:42
von CaptnChaos
dann mach für deinen view eine globale Variable, die immer nur in bestimmten events geupdatet wird.
zB bei einem mausklick.
Verfasst: 28. September 2007 16:45
von q-tee
du meinst "view die zuletzt den mauszeiger bzw den fokus hatte"?
bringt auch nich viel, wenn alle views aktualisiert werden sollen...
Verfasst: 28. September 2007 17:02
von CaptnChaos
hö? das aktualisiert sich doch dann selber oder net? und den sclaeFactor kann man net iwie auch global speichern?
Verfasst: 28. September 2007 17:43
von q-tee
nochmal kurz zur erklärung
zwei views, auf der einen verschieb ich ein objekt, auf der anderen sieht man auch wie es rumgeschoben wird (so wie im
chip-beispiel).
problem: bounding-rect abhängig von der skalierung der view.
klar kann ich die skalierungsfaktoren alle global speichern. aber rausfinden auf welcher view ich mich gerade während der berechnung des bounding-rect befinde kann ich nich...
Verfasst: 28. September 2007 23:44
von CaptnChaos
QHash
Verfasst: 1. Oktober 2007 14:10
von q-tee
sorry, peil ich nich. was hab ich davon?
Verfasst: 1. Oktober 2007 14:24
von CaptnChaos
Mach einen QHash mit deinen Views und den dazugehörigen zoom Faktoren.
Verfasst: 1. Oktober 2007 14:39
von slash-ex
Ich habe auch ein Zoom-Problem. Meins tauchte auf als ich bemerkte, dass wenn ich ein Bild zeichne und dann scale, dass Bild verpixelt.
Also dachte ich mir... zeichne alles was nicht verpixelt, vergrößere und zeichne dann das aktuelle skalierte Bild an die ursprüngliche stelle.
ABER dann tauchte ein Problem auf, dass ich immernoch nicht gelöst habe. Wenn ich vergrößere bleibt im Bildausschnitt die Pixelzahl konstant und wenn ich das Bild auf eine frühere Koordinate setze wenns vergrößert ist, dann ist es deplatziert. Aus diesem Grund wollte ich die Koordinaten zurücktrechnen... Die Konsequenz war, dass genau der selbe Fehler wieder auftritt, nur in einer wesentlich größeren Funktion ): Da hatte ichs aufgegeben. Aber vielleicht weils grad passt, kann mir da auch jemand helfen?!
edit:
was die mit der hash-table meinen, ist, dass du einfach bei einer bestimmten vergrößerung (float) die breite des rect zuordnest (float). aber das ist wohl unnötig...
was du machen musst ist nur:
-ein kleines rechteck zeichnen.
-ein großes zeichnen, mit einer seite die scale*x(kleines rect) entspricht.
feddich
Verfasst: 1. Oktober 2007 15:22
von q-tee
sorry, ich glaub wir reden immernoch aneinander vorbei.
mir is schon klar, dass ich die zoomfaktoren speichern kann. jetzt ist aber das problem: ich befinde mich in der boundingRect-funktion. in dieser kann ich nicht rausfinden wie die aktuelle skalierung ist - ich weiß nämlich nicht für welches view gerade das boundingRect berechnet wird...
in der paint-funktion geht das über "yScale = option->matrix.m22();"
Code: Alles auswählen
QRectF fixRect::boundingRect() const
{
return QRectF(0, 0, width, height * yScale); // woher den Faktor nehmen???
}
und zu dem problem von slash-ex: verrat uns doch mal kurz wie du das bild wo hin zeichnest und wie du skaliert, dann können wir dir glaub besser helfen.