[Qt-jambi-interest] QGraphicsView and coordinates system... (again)
moebius at altern.org
moebius at altern.org
Wed Jul 23 20:04:07 CEST 2008
> moebius at altern.org wrote:
>> Hello !
>>
>> I'm still working on my mathematical function plot program and I still
>> have problems to make it work as expected.
>>
>> Thanks to Eskil, I found the ItemIgnoresTransformations flag that permit
>> to make some items (especially text items) ignoring scale
>> transformations.
>> But item positioning is still a bit confusing for me. Especially when
>> view
>> is resized.
>>
>> I wrote a small snippet to explain my problem. The code below should
>> display an ellipse and a rectangle fitting the view (thanks to
>> fitInView()
>> method). I'd also like to display a label displaying rectangle height at
>> the top left corner outside the rectangle. To do this, once all my
>> objects
>> are created, I set the label position using :
>>
>> label.setPos(scene.sceneRect().left(), scene.sceneRect().top());
>>
>> This works fine except the label is displayed inside the rectangle. To
>> display it outside the rectangle, I substract the width of the label
>> from
>> the x coordinate of its position. So the previous line becomes :
>>
>> label.setPos(scene.sceneRect().left()-label.boundingRect().width(),
>> scene.sceneRect().top());
>>
>> My label is now positioned outside the rectangle, but when I resize the
>> window, the distance between the top left corner of the rectangle and
>> the
>> label is varying. My problem is to make this distance constant. I'd like
>> to be able to put my label at a constant position relatively to the
>> scene
>> bounding rectangle.
>>
> Hi,
>
> The main problem here is that you are trying to stretch QGraphicsView
> beyond its design goals ;-) QGraphicsView was written to suppport a
> scene with nested transformation. The labels or tags you are using here
> are not supported by this model. Using the ignores transformation flag
> you can get some of this behaviour, but not quite as the anchors used to
> position the non-transformed items are still transformed. Their x,y
> position in the scene is still subject to the current scene
> transformation...
>
> This can be acheived, but it is a bit hackish... All of the labels in
> your UI must have an anchor of some sort. In this case I used the
> rectangle and its topleft corner. To avoid the transformation of the
> labels x and y coordinates, I calculate the anchors position in VIEW
> coordinates. Then I apply the offset adjustment, then transform this
> VIEW position into scene space. By doing so and calling the
> adjustLabelToAnchor for every time the anchor item is moved you will get
> the.
>
> QGraphicsView is not the solution to every problem. You might consider
> implementing some functionality of your plotter using QPainter directly.
>
>
> import com.trolltech.qt.core.*;
> import com.trolltech.qt.gui.*;
>
> public class GraphicsViewLabels extends QMainWindow {
> private QGraphicsScene scene;
> private MyGraphicsView view;
>
> private QGraphicsSimpleTextItem label;
> private QGraphicsItemInterface anchor;
>
> public static void main(String[] args) {
> QApplication.initialize(args);
> GraphicsViewLabels test = new GraphicsViewLabels();
> test.show();
> QApplication.exec();
> }
>
> private void adjustLabelToAnchor() {
> QPoint anchorPos =
> view.mapFromScene(anchor.boundingRect().topLeft());
> QPointF labelPos = view.mapToScene(anchorPos.x() - (int)
> label.boundingRect().width(),
> anchorPos.y());
>
> label.setPos(labelPos);
> }
>
> public GraphicsViewLabels(){
> scene = new QGraphicsScene(this);
>
> QGraphicsEllipseItem ellipse = new QGraphicsEllipseItem(10.0,
> 20.0, 250.0, 150.0);
> scene.addItem(ellipse);
>
> QGraphicsRectItem rect = new QGraphicsRectItem(10.0, 20.0,
> 250.0, 150.0);
> scene.addItem(rect);
> anchor = rect;
>
> label = new
> QGraphicsSimpleTextItem(String.valueOf(-scene.sceneRect().top()));
> /*
> * With this line the label position relative to other items
> change when
> window is resized
> */
> /*
> * With this line the label position relative to other items
> doesn't
> change when window is resized
> */
> // label.setPos(scene.sceneRect().left(),
> scene.sceneRect().top());
>
> label.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations,
> true);
> scene.addItem(label);
>
> view = new MyGraphicsView(scene);
> this.setCentralWidget(view);
>
> this.resize(new QSize(400,
> 300).expandedTo(this.minimumSizeHint()));
> }
>
> class MyGraphicsView extends QGraphicsView {
>
> public MyGraphicsView(QGraphicsScene scene) {
> super(scene);
> }
>
> @Override
> protected void resizeEvent(QResizeEvent event) {
> super.resizeEvent(event);
> fitInView(scene.sceneRect(),
> Qt.AspectRatioMode.IgnoreAspectRatio);
> scale(0.8, 0.8);
>
> adjustLabelToAnchor();
>
> }
> }
> }
>
>
Thank you for your response.
Your solution seems actually a bit tricky. But it's still interesting to
see what a master-of-the-jambi-world can do.
For practical I directly used the QPainter to solve this problem.
Anyway, thank you very much again.
More information about the Qt-jambi-interest
mailing list