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.