2010-08-23 3 views
4

Есть ли способ ограничить область, в которой QGraphicsItem, например QRect, может быть перемещен при установке setFlag (ItemIsMovable)?Ограничить перемещаемую область qgraphicsitem

Я новичок в pyqt и пытаюсь найти способ перемещения элемента с помощью мыши и ограничивать его только по вертикали/по горизонтали.

Спасибо!

ответ

2

Возможно, вам понадобится переопределить функцию itemChange() функции QGraphicsItem. Псевдокод:

if (object position does not meet criteria): 
    (move the item so its position meets criteria) 

Repossitioning деталь заставит itemChange получить колл снова, но это нормально, потому что деталь будет possitioned правильно и не будет перемещен снова, так что вы не будете застряли в бесконечном цикле.

3

повторно реализовать mouseMoveEvent (самостоятельно, события) в QGraphicScene как следующее:

def mousePressEvent(self, event): 

    self.lastPoint = event.pos() 

def mouseMoveEvent(self, point): 

    if RestrictedHorizontaly: # boolean to trigger weather to restrict it horizontally 
     x = point.x() 
     y = self.lastPoint.y() 
     self.itemSelected.setPos(QtCore.QPointF(x,y))<br> # which is the QgraphicItem that you have or selected before 

надеюсь, что это помогает

4

Если вы хотите сохранить ограниченную область, которую вы можете переопределить ItemChanged()

Declare:

#ifndef GRAPHIC_H 
#define GRAPHIC_H 
#include <QGraphicsRectItem> 
class Graphic : public QGraphicsRectItem 
{ 
public: 
    Graphic(const QRectF & rect, QGraphicsItem * parent = 0); 
protected: 
    virtual QVariant itemChange (GraphicsItemChange change, const QVariant & value); 
}; 

#endif // GRAPHIC_H 

реализация: ItemSendsGeometryChanges флаг необходим, чтобы захватить изменение позиции QGraphicsItem

#include "graphic.h" 
#include <QGraphicsScene> 

Graphic::Graphic(const QRectF & rect, QGraphicsItem * parent) 
    :QGraphicsRectItem(rect,parent) 
{ 
    setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges); 
} 

QVariant Graphic::itemChange (GraphicsItemChange change, const QVariant & value) 
{ 
    if (change == ItemPositionChange && scene()) { 
     // value is the new position. 
     QPointF newPos = value.toPointF(); 
     QRectF rect = scene()->sceneRect(); 
     if (!rect.contains(newPos)) { 
      // Keep the item inside the scene rect. 
      newPos.setX(qMin(rect.right(), qMax(newPos.x(), rect.left()))); 
      newPos.setY(qMin(rect.bottom(), qMax(newPos.y(), rect.top()))); 
      return newPos; 
     } 
    } 
    return QGraphicsItem::itemChange(change, value); 
} 

Затем мы определяем прямоугольник сцены, в этом случае будет 300x300

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent) 
{ 
    QGraphicsView * view = new QGraphicsView(this); 
    QGraphicsScene * scene = new QGraphicsScene(view); 
    scene->setSceneRect(0,0,300,300); 
    view->setScene(scene); 
    setCentralWidget(view); 
    resize(400,400); 

    Graphic * graphic = new Graphic(QRectF(0,0,100,100)); 
    scene->addItem(graphic); 
    graphic->setPos(150,150); 

} 

Это должно держать график в пределах области, удачи

+0

Он работает очень хорошо, ожидайте, что графический элемент можно будет немного потянуть за сцену в правой и нижней области, потому что вы используете верхние левые координаты окна Graphic, чтобы проверить, находится ли объект внутри сцены rect , – danger89

+0

Это могло бы решить эту проблему: http://stackoverflow.com/a/22559758/518879 – danger89

Смежные вопросы