Skip to content
QtWS25 Last Chance
  • 0 Votes
    2 Posts
    3k Views
    VagabondV
    Okay, I have come up with a solution. I have setup a better handling for the hittest evaluation. I first check which side of the intersected boundingbox the moved item is closest to. Then I set the x, or y coordinate accordingly. I added some helper functions for this, to compute point-line distance and closest side of a rect to a point. They are all included in the snippet below. NOTE: the collision test will also evaluate and prohibit the item to exceed the scene bounds. It will also only solve, overlapping one other item. If the border test results in another overlap I simply set the position back to where it was prior to mouse move. Works a lot nicer than my initial implementation though. enum CustomGraphicsItem::BOX_SIDE { LEFT, RIGHT, UPPER, LOWER }; void CustomGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* e) { if(mode_ == MOVE) { QPointF p = pos(); QGraphicsItem::mouseMoveEvent(e); QPointF p_new = pos(); QList<QGraphicsItem*> col_it = collidingItems(Qt::IntersectsItemBoundingRect); if(col_it.size() > 0) { qreal x_min = col_it[0]->pos().x() - boundingRect().width(); qreal x_max = col_it[0]->pos().x() + col_it[0]->boundingRect().width(); qreal y_min = col_it[0]->pos().y() - boundingRect().height(); qreal y_max = col_it[0]->pos().y() + col_it[0]->boundingRect().height(); QRectF rect(QPointF(x_min, y_min), QPointF(x_max, y_max)); switch(closestSide(p_new, rect)) { case LEFT: p_new.setX(x_min); break; case RIGHT: p_new.setX(x_max); break; case UPPER: p_new.setY(y_min); break; case LOWER: p_new.setY(y_max); break; } setPos(p_new); } // check if item in scene bounds qreal max_x = scene()->width() - boundingRect().width(); qreal max_y = scene()->height() - boundingRect().height(); if (x() < 0) setPos(0, y()); else if (x() > max_x) setPos(max_x, y()); if (y() < 0) setPos(x(), 0); else if (y() > max_y) setPos(x(), max_y); // if still colliding set pos back to start col_it = collidingItems(Qt::IntersectsItemBoundingRect); if(col_it.size() > 0) setPos(p); } } qreal CustomGraphicsItem::distance(const QPointF &p, const QLineF &l) { QPointF p1 = l.p1(); QPointF p2 = l.p2(); qreal x = p.x() - p1.x(); qreal y = p.y() - p1.y(); qreal x2 = p2.x() - p1.x(); qreal y2 = p2.y() - p1.y(); // if line is a point, return distance between point and one line node qreal norm = sqrt(x2*x2 + y2*y2); if (norm <= std::numeric_limits<int>::epsilon()) return sqrt(x*x + y*y); // distance return fabs(x*y2 - y*x2) / norm; } CustomGraphicsItem::BOX_SIDE CustomGraphicsItem::closestSide(const QPointF &p, const QRectF &rect) { qreal x_min = rect.x(); qreal x_max = rect.x() + rect.width(); qreal y_min = rect.y(); qreal y_max = rect.y() + rect.height(); qreal temp_dist = 0; // left QLineF l(QPointF(x_min, y_min), QPointF(x_min, y_max)); qreal min_dist = distance(p,l); BOX_SIDE side = LEFT; // right l.setPoints(QPointF(x_max,y_min), QPointF(x_max, y_max)); temp_dist = distance(p,l); if(temp_dist < min_dist) { min_dist = temp_dist; side = RIGHT; } // upper l.setPoints(QPointF(x_min, y_min), QPointF(x_max, y_min)); temp_dist = distance(p,l); if(temp_dist < min_dist) { min_dist = temp_dist; side = UPPER; } // lower l.setPoints(QPointF(x_min, y_max), QPointF(x_max, y_max)); temp_dist = distance(p,l); if(temp_dist < min_dist) { min_dist = temp_dist; side = LOWER; } return side; }
  • Best way to handle ...

    General and Desktop qgraphicsitem
    4
    0 Votes
    4 Posts
    1k Views
    SGaistS
    It's not a trick, that's how you use dynamic_cast. You don't create a new object. You will use a local variable that is a pointer to your object or null if colItems.at(i) is not a pointer to an A object. Local variable that will be destroyed at the end of the function.
  • 0 Votes
    16 Posts
    5k Views
    J
    I think I have found the problem. I went through the source code of the QGraphicsTextItem and came across the private _q_updateBoundingRect. In there there is a line: if (size == qq->m_boundingRect.size() || pageSize.height() != -1) return; It looks like the pageSize.height() != -1 part is the problem. I have removed it and it seems to be working!
  • 0 Votes
    5 Posts
    2k Views
    BjornWB
    @Wieland I was thinking about QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant & value) or similar. That does not use the signal/slot system. Anyway, gonna change my code to use slots.
  • When QGraphicsItem meets heritage

    Solved General and Desktop heritage qgraphicsitem
    6
    0 Votes
    6 Posts
    2k Views
    W
    Yep, it's fixed. Topic->setAsSolved(true)
  • QGraphicsScene borders ?

    Unsolved General and Desktop qgraphicsscene qgraphicsitem borders collisions
    3
    0 Votes
    3 Posts
    2k Views
    W
    @Joel-Bodenmann That's the manual way i talked about uptop but thanks anyways :) It reassures me that i'm not "re-inventing" the wheel by applying this method .
  • 0 Votes
    4 Posts
    1k Views
    W
    Yep , fixed !! Biggest achievement of ma layf. Topic->setAsSolvedPolicy(Qt::AlwaysTrue);
  • Unclear Map Definitions

    Solved Game Development qgraphicsitem qgraphicsscene
    2
    0 Votes
    2 Posts
    1k Views
    Joel BodenmannJ
    I'd recommend reading this article which explains everything fairly well: Coordinate System As the article explains, each graphics item maintains it's own coordinate system. The methods you are referring to are used to translate coordinates between those items, between the items and the scene and so on. I hope that reading that article will help, otherwise feel free to ask if clarification is needed.
  • Focusing on item

    Solved Game Development qgraphicsitem qgraphicsscene qabstractproxym
    5
    0 Votes
    5 Posts
    2k Views
    W
    I had misconfigured ensureVisible's margins , and the view's size and the scene's rect . Now it works fine :)
  • 0 Votes
    1 Posts
    1k Views
    No one has replied
  • 1 Votes
    10 Posts
    5k Views
    mrjjM
    Hehe good found :)
  • QPainterPath from list of points

    Solved General and Desktop qpainterpath qgraphicsitem shape
    24
    0 Votes
    24 Posts
    13k Views
    Joel BodenmannJ
    @mrjj Well, thanks to you and @kshegunov too. You guys are amazing!
  • 0 Votes
    1 Posts
    2k Views
    No one has replied
  • Pen thickness in pixel for QGraphicsItem

    Unsolved General and Desktop qgraphicsitem qpen pixel qpainter
    1
    0 Votes
    1 Posts
    999 Views
    No one has replied
  • 0 Votes
    6 Posts
    2k Views
    SGaistS
    No, my idea was to build your set of resizable widgets with QSplitter and then add that QSplitter to your scene
  • 0 Votes
    1 Posts
    992 Views
    No one has replied
  • 0 Votes
    6 Posts
    5k Views
    A
    Thank you for your answere. I've already tried that but it wasn't the solution. I've figured out that the problem occures when turning on OpenGL rendering. I guess it has to do with my hibryd graphic system. My main card has some serious problems so I can't run Optirun right now and I guess my secondary GPU does not support the required features (only OpenGL 3.X). I'm not shure about that but as I said: turning off the OpenGL rendering solved that problem for me. Maybe it helps others. Have a nice day everyone
  • 0 Votes
    2 Posts
    2k Views
    T
    @tmoranduzzo I added item_pop->setPixmap(QPixmap::fromImage(transfer_image)); to update the view and that solved my problem
  • 1 Votes
    5 Posts
    3k Views
    A
    @Joel-Bodenmann To elaborate on your answer: The boundingRect() must include every pixel that you intend to paint to in your own item's paint method. That includes e.g. pixels that are outside your item proper, but painted to due to a wide pen. (Calculating the correct boundingRect for items with wide cosmetic pens can be a real pain.)