2016-06-10 2 views
0

Вот что я хочу сделать.Как выровнять прямоугольник слева от QGraphicsView без масштабирования сцены?

Мне нужно нарисовать в QGraphicsView ряд прямоугольников, которые выровнены влево и вправо. Под этим я подразумеваю, что если прямоугольник i имеет позицию (0, y), прямоугольник i + 1 должен иметь положение (0, max), где max таков, что правая сторона прямоугольника «касается» правой части QGraphicsView.

При изменении размера окна мне нужно пересчитать значение max так, чтобы прямоугольник всегда касался правой стороны экрана.

Вот как я добавляю свою сцену (это ссылается на класс, который наследует QGraphicsView)

scene = new QGraphicsScene(this); 
this->setScene(scene); 
this->setAlignment(Qt::AlignTop|Qt::AlignLeft); 

Чтобы добавить прямоугольник, который прикасается левую границу я добавить его (0, yvalue, ширина, высота).

Как рассчитать значение X, чтобы прямоугольник коснулся правой границы?

+1

Можете ли вы использовать QML? Недавно я переключился с QGraphicsView на QML для рисования таких вещей, и влияние производительности огромно. – cheez

+0

Я даже не знаю, что такое QML ... если честно. Я использую Qt 5.1.1. это доступно? Как насчет совместимости? Я забочусь об этом больше, чем о производительности ... – aarelovich

+1

О, тогда вам это понравится: https://doc.qt.io/qt-5/qmlapplications.html Совместимость прекрасна. Я отправляю приложения QML на 3 настольных компьютерах, но для этого я использую Qt 5.6. Я не мог рассказать вам историю совместимости с Qt 5.1.1. – cheez

ответ

0

Этот маленький пример должен рассчитать сдвиг и переместить все предметы из списка или списка элементов, основываясь на желаемом выравнивании (я показал правильно, но пусть, в центре, сверху, снизу будет то же самое).

QRectF refRect = scene()->sceneRect(); 
QList<QGraphicsItem*> sel = allItemsYouWantAligned; // scene()->selectedItems(); for example 

foreach(QGraphicsItem* selItem, sel) 
{ 
    qreal dx = 0, dy = 0; 
    QRectF itemRect = selItem->mapToScene(selItem->boundingRect()).boundingRect(); 
    if(align_right) 
     dx = refRect.right() - itemRect.right(); 
    else 
     .. calculate either dx or dy on how you want to align 
    selItem->moveBy(dx, dy); 
} 

Перечитывая вопрос - я вижу, что ты на самом деле не нужно, чтобы переместить прямоугольник, но создавать новые большие и большие прямоугольники.

Ваше решение достаточно просто. Если вы хотите изменить размер, а не двигаться - вам придется setRect() на ваши вопросы по приращению дх:

QRectF r = selItem->rect(); 
r.setWidth(r.width + dx); 
selItem->setRect(r); 
+0

Это не сработало, так как dx всегда вычисляется как 0. – aarelovich

+0

@aarelovich - странно, это может быть только 0, если стороны 'right()' вашего холста и элемента уже совпадают. – Thalia

+0

Я попробую еще раз (я удалил код со всеми изменениями, которые я сделал) и заглянул обратно ... – aarelovich

0

Ok. Так что это должно произойти в событии изменения размера QGraphicsView. Но это делает то, что я хотел:

void AView::resized(){ 

    scene->clear(); 
    QSize newsize = this->size(); 

    qreal w = newsize.width()*.99; 
    qreal h = newsize.height()*.99; 
    this->setSceneRect(0,0,w,h); 
    scene->setSceneRect(0,0,w,h); 

    qreal rectwidth = 100; 
    qreal newx = w - rectwidth; 
    left = new QGraphicsRectItem(0,0,rectwidth,100); 
    left->setBrush(QBrush(Qt::red)); 
    right = new QGraphicsRectItem(newx,100,rectwidth,100); 
    right->setBrush(QColor(Qt::blue)); 

    scene->addItem(left); 
    scene->addItem(right); 

} 

Таким образом, синий прямоугольник почти всегда находится на границе. Также нет растяжения изображения. Между правыми границами возникает разрыв, который увеличивается из-за изменения размера окна, но кажется, что размер, возвращаемый этим -> size(), немного больше, чем «белая область», которую вы видите на экране. Добавление .99 дает гораздо лучшие результаты из моих экспериментов.

+0

Это работает, если вы хотите добавлять новые элементы при каждом изменении размера - вы можете сначала удалить старые?Кажется, это тяжелая работа :-) Это проще (и избежать утечки памяти), если вы просто установитеRect() слева и справа. – Thalia

+0

Это всего лишь пример более сложной вещи, которую я хотел сделать. И да, я хотел избежать создания элементов при каждом изменении размера. Но это сработало. Дело в том, что scene-> clear фактически удаляет элементы (я бы предпочел, если бы он просто удалил их со сцены, но, увы ...), поэтому, если я делаю ясную сцену, мне нужно каждый раз воссоздавать их ... – aarelovich

+0

Что вы ожидаете от «ясного»? И - если вы просто не устанавливаете право на свои предметы, ваша программа будет использовать все больше и больше памяти каждый раз, когда вы вызываете эту функцию, в конечном итоге выйдет из строя - это то, что означает утечка памяти. – Thalia