GraphicsView Rechtecke verschieben

Alles rund um die Programmierung mit Qt
Antworten
paule22
Beiträge: 18
Registriert: 1. August 2010 21:25

GraphicsView Rechtecke verschieben

Beitrag von paule22 »

Hallo,

habe folgenden Code, der dazu dient, Rechtecke zu verschieben.
Allerdings haut da was nicht hin, wenn ich item1 verschiebe, dann
verschiebt sich item2 oder auch andersherum.
Woran kann das liegen?
Danke für Codesnippets und Sachdienliche Hinweise

Code: Alles auswählen

#include <QtGui>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>
#include "designergraphicsview.h"

DesignerGraphicsView::DesignerGraphicsView(QWidget *parent) :
    QGraphicsView(parent)
{
    scene = new QGraphicsScene(this);
    this->setScene(scene);
    this->setGeometry(0,0,800,600);

    drag_item = nullptr;

    item1 = new DesignerItem;
    item2 = new DesignerItem;

    item1->setGeometry(4,4,100,100);
    item1->signal_mouse_press.connect(
                boost::bind(
                    &DesignerGraphicsView::OnMousePress,
                    this,_1)
                );

    item2->setGeometry(54,54,100,100);
    item2->signal_mouse_press.connect(
                boost::bind(
                    &DesignerGraphicsView::OnMousePress,
                    this,_1)
                );

    resizer = new QGraphicsRectItem;
    resizer->setRect(0,0, 106,106);
    resizer->setPen(QPen(Qt::red));
    resizer->setBrush(Qt::yellow);
    resizer->hide();

    scene->addItem(resizer);

    proxy1 = scene->addWidget(item1);
    proxy1->setPos(4,4);
    proxy1->setFlag(QGraphicsItem::ItemIsMovable,true);
    item_objects[item1] = proxy1;

    proxy2 = scene->addWidget(item2);
    proxy2->setPos(34,34);
    proxy2->setFlag(QGraphicsItem::ItemIsMovable,false);
    item_objects[item2] = proxy2;
}

void DesignerGraphicsView::OnMousePress(DesignerItem *item)
{
    assert(item);
    drag_item = item;

    resizer->show();

    if (drag_item == item1) {
        proxy1->setFlag(QGraphicsItem::ItemIsMovable,true);
        proxy2->setFlag(QGraphicsItem::ItemIsMovable,false);
    }
    else if (item == item2) {
        proxy1->setFlag(QGraphicsItem::ItemIsMovable,false);
        proxy2->setFlag(QGraphicsItem::ItemIsMovable,true);
    }
}

void DesignerGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (drag_item) {
        QPointF p = this->mapToScene(event->pos());
        item_objects[drag_item]->setPos(p-
        drag_item->m_pos);

        QPointF p2 = p;
        p2.setX(p2.x()-qreal(4.0));
        p2.setY(p2.y()-qreal(4.0));

        resizer->setPos(p2-drag_item->m_pos);
    }
}

void DesignerGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    drag_item = nullptr;
}


#ifndef DESIGNERGRAPHICSVIEW_H
#define DESIGNERGRAPHICSVIEW_H

#include <QWidget>
#include <QGraphicsView>

#include "designeritem.h"

class DesignerGraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    explicit DesignerGraphicsView(QWidget *parent = 0);

signals:

public slots:

protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private:
    QGraphicsScene *scene;

    DesignerItem *drag_item;
    QGraphicsRectItem *resizer;

    QGraphicsProxyWidget *proxy1;
    QGraphicsProxyWidget *proxy2;

    DesignerItem *item1;
    DesignerItem *item2;

    std::map<DesignerItem*, QGraphicsProxyWidget*> item_objects;
    void OnMousePress(DesignerItem *item);
};

#endif // DESIGNERGRAPHICSVIEW_H
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: GraphicsView Rechtecke verschieben

Beitrag von Christian81 »

Was ist DesignerItem für ein Typ und wer implementiert signal_mouse_press() ? Warum überhaupt boost mit drin?

/edit: Ah sehe gerade dass dies Qt4 sein könnte - dann natürlich boost für das connect. Oder eben etwas anders schreiben damit es auch jeder versteht :)
Ich schätze dass das Signal OnMousePress() später kommt als mouseMoveEvent(). Kann man ja einfach mit Debugausgaben sehen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
paule22
Beiträge: 18
Registriert: 1. August 2010 21:25

Re: GraphicsView Rechtecke verschieben

Beitrag von paule22 »

Hallo Christian,

DesignerItem ist ein QWidget
Hope this Helps.

suche immer noch den Fehler.

Code: Alles auswählen

#ifndef __DESIGNER_ITEM_H__
#define __DESIGNER_ITEM_H__

#include <QWidget>
#include <QtCore>
#include <QtGui>
#include <boost/signals2.hpp>

class DesignerItem : public QWidget
{
  Q_OBJECT

public:
    explicit DesignerItem(QWidget *p = 0, Qt::WindowFlags f = 0);
    boost::signals2::signal<void (DesignerItem*)> signal_mouse_press;

    QPointF m_pos;
    QWidget *_p;

protected:
    void mousePressEvent(QMouseEvent * event);
    void paintEvent(QPaintEvent * event);

private:
    QPainter p;
};

#endif

#include "designeritem.h"

DesignerItem::DesignerItem(QWidget *p, Qt::WindowFlags f)
  : QWidget(p,f)
{
    _p = p;
}

void DesignerItem::mousePressEvent(QMouseEvent * event)
{
    m_pos = event->windowPos();
    signal_mouse_press(this);
    QWidget::mousePressEvent(event);
}

void DesignerItem::paintEvent(QPaintEvent *event)
{
    QRectF rectangle(0.0, 0.0, 97.0, 97.0);
    QBrush red(Qt::red);

    p.begin(this);
    p.drawRect(rectangle);
    p.end();
}
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: GraphicsView Rechtecke verschieben

Beitrag von Christian81 »

Wie gesagt - warum boost wenn es auch ohne geht und meine Vermutung hast du noch nicht verifiziert.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
paule22
Beiträge: 18
Registriert: 1. August 2010 21:25

Re: GraphicsView Rechtecke verschieben

Beitrag von paule22 »

Hallo,

sodele, jetzt habe ich den boost kram rausgenommen,
und Qt5 Board-Eigene Mittel verwendet.
Aber das Problem besteht weiterhin.

Code: Alles auswählen

#ifndef __DESIGNER_ITEM_H__
#define __DESIGNER_ITEM_H__

#include <QWidget>
#include <QtCore>
#include <QtGui>
#include <QGraphicsRectItem>

class DesignerItem : public QWidget
{
  Q_OBJECT

public:
    explicit DesignerItem(QWidget *p = 0, Qt::WindowFlags f = 0);

    QPointF m_pos;
    QWidget *_p;

    class DesignerGraphicsView *view;

protected:
    void mousePressEvent(QMouseEvent * event);
    void paintEvent(QPaintEvent * event);

private:
    QPainter p;
};

#endif


#include "designergraphicsview.h"
#include "designeritem.h"

DesignerItem::DesignerItem(QWidget *p, Qt::WindowFlags f)
  : QWidget(p,f)
{
    _p = p;
}

void DesignerItem::paintEvent(QPaintEvent *event)
{
    QRectF rectangle(0.0, 0.0, 97.0, 97.0);
    QBrush red(Qt::red);

    p.begin(this);
    p.drawRect(rectangle);
    p.end();
}

void DesignerItem::mousePressEvent(QMouseEvent *event)
{
    view->drag_item = this;
    qDebug() << this;

    m_pos = event->windowPos();
    view->resizer->show();

    QWidget::mousePressEvent(event);
}


#include <QObject>
#include <QtGui>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>
#include <QVector>
#include "designergraphicsview.h"

QVector<QGraphicsProxyWidget *> proxies;

DesignerGraphicsView::DesignerGraphicsView(QWidget *parent) :
    QGraphicsView(parent)
{
    scene = new QGraphicsScene(this);
    this->setScene(scene);
    this->setGeometry(0,0,800,600);

    drag_item = nullptr;

    item1 = new DesignerItem; item1->view = this;
    item2 = new DesignerItem; item2->view = this;

    item1->setGeometry(4,4,100,100);
    item2->setGeometry(54,54,100,100);

    resizer = new QGraphicsRectItem;
    resizer->setRect(0,0, 106,106);
    resizer->setPen(QPen(Qt::red));
    resizer->setBrush(Qt::yellow);
    resizer->hide();

    scene->addItem(resizer);

    proxy1 = scene->addWidget(item1);
    proxy1->setPos(4,4);
    proxy1->setFlag(QGraphicsItem::ItemIsMovable,true);
    item_objects[item1] = proxy1;
    proxies << proxy1;

    proxy2 = scene->addWidget(item2);
    proxy2->setPos(34,34);
    proxy2->setFlag(QGraphicsItem::ItemIsMovable,true);
    proxies << proxy2;
    item_objects[item2] = proxy2;
}

void DesignerGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (drag_item) {
        QPointF p = this->mapToScene(event->pos());
        item_objects[drag_item]->setPos(p-drag_item->m_pos);

        QPointF p2 = p;
        p2.setX(p2.x()-4.0);
        p2.setY(p2.y()-4.0);

        resizer->setPos(p2-drag_item->m_pos);
    }
}

void DesignerGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    drag_item = nullptr;
}



#ifndef DESIGNERGRAPHICSVIEW_H
#define DESIGNERGRAPHICSVIEW_H

#include <QWidget>
#include <QGraphicsView>

#include "designeritem.h"

class DesignerGraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    explicit DesignerGraphicsView(QWidget *parent = 0);

signals:

public slots:

protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private:
    QGraphicsScene *scene;

public:
    DesignerItem *drag_item;
    QGraphicsRectItem *resizer;

    QGraphicsProxyWidget *proxy1;
    QGraphicsProxyWidget *proxy2;

    DesignerItem *item1;
    DesignerItem *item2;

    std::map<DesignerItem*, QGraphicsProxyWidget*> item_objects;
};

#endif // DESIGNERGRAPHICSVIEW_H
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: GraphicsView Rechtecke verschieben

Beitrag von Christian81 »

Ich schätze dass das Signal OnMousePress() später kommt als mouseMoveEvent(). Kann man ja einfach mit Debugausgaben sehen.
Mal geprüft ob ich recht habe?
Auch hier ein Hinweis: Zugriff auf Member-Variablen einer anderen Klasse sind nicht gerade guter Stil.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
paule22
Beiträge: 18
Registriert: 1. August 2010 21:25

Re: GraphicsView Rechtecke verschieben

Beitrag von paule22 »

ja, wird mousePressEvent wird zuerst aufgerufen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: GraphicsView Rechtecke verschieben

Beitrag von Christian81 »

Dann sollte in drag_item auch das richtige Item stehen. Am besten beiden Items einen ObjectName geben und diesen per qDebug() im moveEvent ausgeben um wirklich sicher zu gehen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
paule22
Beiträge: 18
Registriert: 1. August 2010 21:25

Re: GraphicsView Rechtecke verschieben

Beitrag von paule22 »

ja, werden sie, mit jeweils unterschiedlichen Pointern.
Das Problem ist, dass, wenn ich beim 1. Mausklick und Move
die beiden items sich bewegen.
Es werden auch 2mal Mausclicks aktiviert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: GraphicsView Rechtecke verschieben

Beitrag von Christian81 »

Ich wüsste nicht warum. Kannst Du ein minimales, kompilierbares Beispiel als zip-Datei anhängen damit ich es mal komplett anschauen kann?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
paule22
Beiträge: 18
Registriert: 1. August 2010 21:25

Re: GraphicsView Rechtecke verschieben

Beitrag von paule22 »

Hallo,

inzwischen habe ich es hinbekommen *freu :-)
Allerdings ist jetzt noch eines zu klären:
Wie bekommt man das item1, was sich hinter dem item2 befindet
in den Vordergrund?
Im Moment läuft es so, das es erstmal verschiebbar ist.
Und wie kann man dann den "resizer" rect mit nach vorne verschieben?

Gruß

Code: Alles auswählen

#include <QObject>
#include <QtGui>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>
#include <QVector>
#include "designergraphicsview.h"

QVector<QGraphicsProxyWidget *> proxies;

DesignerGraphicsView::DesignerGraphicsView(QWidget *parent) :
    QGraphicsView(parent)
{
    scene = new QGraphicsScene(
                qreal(0.0  ), qreal(0.0),
                qreal(800.0), qreal(600.0),
                this);

    this->setScene(scene);
    this->setGeometry(0,0,800,600);

    drag_item = nullptr;

    item1 = new DesignerItem; item1->view = this;
    item2 = new DesignerItem; item2->view = this;

    item1->setGeometry(0,0,100,100);
    item2->setGeometry(0,0,100,100);

    resizer = new QGraphicsRectItem;
    resizer->setRect(0,0, 106,106);
    resizer->setPen(QPen(Qt::red));
    resizer->setBrush(Qt::yellow);
    resizer->hide();

    scene->addItem(resizer);

    proxy1 = scene->addWidget(item1);
    proxy1->setPos(104,104);
    proxy1->setFlag(QGraphicsItem::ItemIsMovable,true);
    item_objects[item1] = proxy1;
    proxies << proxy1;

    proxy2 = scene->addWidget(item2);
    proxy2->setPos(134,134);
    proxy2->setFlag(QGraphicsItem::ItemIsMovable,true);
    proxies << proxy2;
    item_objects[item2] = proxy2;
}

void DesignerGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (item_objects[drag_item]) {
        qDebug() << "moveMaus";

        QPointF p = this->mapToScene(event->pos());
        qDebug() << p;
        item_objects[drag_item]->setPos(p-drag_item->m_pos);

        QPointF p2 = p;
        p2.setX(p2.x()-4.0);
        p2.setY(p2.y()-4.0);

        resizer->setPos(p2-drag_item->m_pos);
    }
}

void DesignerGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    drag_item = nullptr;
}

#ifndef DESIGNERGRAPHICSVIEW_H
#define DESIGNERGRAPHICSVIEW_H

#include <QWidget>
#include <QGraphicsView>

#include "designeritem.h"

class DesignerGraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    explicit DesignerGraphicsView(QWidget *parent = 0);

protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private:
    QGraphicsScene *scene;

public:
    DesignerItem *drag_item;
    QGraphicsRectItem *resizer;

    QGraphicsProxyWidget *proxy1;
    QGraphicsProxyWidget *proxy2;

    DesignerItem *item1;
    DesignerItem *item2;

    std::map<DesignerItem*, QGraphicsProxyWidget*> item_objects;
};

#endif // DESIGNERGRAPHICSVIEW_H


#include "designergraphicsview.h"
#include "designeritem.h"

DesignerItem::DesignerItem(QWidget *p, Qt::WindowFlags f)
  : QWidget(p,f)
{
    _p = p;
}

void DesignerItem::paintEvent(QPaintEvent *event)
{
    {
        QRect rectangle(0,0, 97,97);
        QBrush red(Qt::red);

        p.begin(this);
        p.drawRect(rectangle);
        p.end();
    }
}

void DesignerItem::mousePressEvent(QMouseEvent *event)
{
    view->drag_item = this;
    qDebug() << "MausPress:" << this;

    m_pos = event->localPos();
    view->resizer->show();

    QWidget::mousePressEvent(event);
}


#ifndef __DESIGNER_ITEM_H__
#define __DESIGNER_ITEM_H__

#include <QWidget>
#include <QtCore>
#include <QtGui>
#include <QGraphicsRectItem>

class DesignerItem : public QWidget
{
  Q_OBJECT

public:
    explicit DesignerItem(QWidget *p = 0, Qt::WindowFlags f = 0);

    QPointF m_pos;
    QWidget *_p;

    class DesignerGraphicsView *view;

protected:
    void mousePressEvent(QMouseEvent * event);
    void paintEvent(QPaintEvent * event);

private:
    QPainter p;
};

#endif
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: GraphicsView Rechtecke verschieben

Beitrag von Christian81 »

Jedes QGraphicsItem hat eine Z-Value -> setZValue()/zValue()
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten