QGraphicsItem copy inside QGraphicScenes
-
In order to try QGraphicsItem copy inside QGraphicScenes, I subclass QGraphicsRectItem that show an image ....
#ifndef HIGHLIGHTRECTITEM_H #define HIGHLIGHTRECTITEM_H #include <QGraphicsRectItem> #include <QPen> #include <QLabel> #include <QGraphicsScene> #include <QGraphicsView> #include <QGraphicsItem> #include <QGraphicsRectItem> #include <QGraphicsPolygonItem> #include <QDesktopWidget> #include <QDialog> #include <QWidget> #include <QWidgetAction> #include <QWidgetData> #include <QWidgetItem> #include <QPixmap> #include <QtWidgets/qstyle.h> #include <QGraphicsRectItem> #include <QGraphicsSceneMouseEvent> #include <QPointF> #include <QObject> class HighlightRectItem : public QGraphicsRectItem { public: static QImage Boximg; static QImage scaleBoximg; static QImage realBoximg; static QPoint ImgPosition; HighlightRectItem(QGraphicsRectItem *parent = 0); bool selectRectItem; void setAnchorPoint(const QPointF& anchorPoint); void setImageDim(QImage realImage, int dXImage, int dYImage); void setImagePos(int Xspace, int Yspace); void getPoint(QPointF myPointBox); QPointF lastBox(); public slots: protected: void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); protected slots: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QPen m_pen; QPointF anchorPoint; bool m_dragged; int dimXImage; int dimYImage; QPointF m_lastBox; signals: //void getterPoint(QPointF); // void clicked(bool); }; #endif // HIGHLIGHTRECTITEM_H
cpp ....
#include "highlightrectitem.h" #include <QPainter> #include <QPointF> #include <QDebug> HighlightRectItem::HighlightRectItem(QGraphicsRectItem *parent) : QGraphicsRectItem(parent), m_dragged(false) { setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemSendsGeometryChanges); setAcceptHoverEvents(true); selectRectItem = false; /*dimXImage = int(400/4); dimYImage = int(600/4); scaleBoximg = Boximg.scaled(dimXImage, dimYImage ,Qt::IgnoreAspectRatio); ImgPosition.setX(int(50/4)); ImgPosition.setY(int(50/4));*/ } QImage HighlightRectItem::Boximg("/home/firstimg-qt.png"); QImage HighlightRectItem::scaleBoximg("/home/niceimg-qt.png"); QPoint HighlightRectItem::ImgPosition(0,0); void HighlightRectItem::setImageDim(QImage realImage, int dXImage, int dYImage) { HighlightRectItem::scaleBoximg = realImage.scaled(dXImage, dYImage , Qt::IgnoreAspectRatio); } void HighlightRectItem::getPoint(QPointF myPointBox) { m_lastBox = myPointBox; } QPointF HighlightRectItem::lastBox() { return m_lastBox; } void HighlightRectItem::setImagePos(int Xspace, int Yspace) { HighlightRectItem::ImgPosition.setX(Xspace); HighlightRectItem::ImgPosition.setY(Yspace); } void HighlightRectItem::setAnchorPoint(const QPointF &anchorPoint) { this->anchorPoint = anchorPoint; } void HighlightRectItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { m_pen.setColor(Qt::red); update(); } void HighlightRectItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { m_pen.setColor(Qt::green); update(); } void HighlightRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if(selectRectItem) { selectRectItem = false; } else { selectRectItem = true; } } void HighlightRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { m_dragged = true; QGraphicsRectItem::mouseMoveEvent(event); } void HighlightRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { QPointF thisBox(0,0); if(m_dragged){ QList<QGraphicsItem*> colItems = collidingItems(); if(colItems.isEmpty()){ this->setPos(anchorPoint); } else { QGraphicsItem* closestItem = colItems.at(0); qreal shortestDist = 100000; foreach(QGraphicsItem* item, colItems){ QLineF line(item->sceneBoundingRect().center(), this->sceneBoundingRect().center()); if(line.length() < shortestDist){ shortestDist = line.length(); closestItem = item; } } this->setPos(closestItem->scenePos()); thisBox.rx() = this->pos().rx(); thisBox.ry() = this->pos().ry(); getPoint(thisBox); //qDebug() << this->pos(); } m_dragged = false; } QGraphicsRectItem::mouseReleaseEvent(event); } void HighlightRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { //painter->; painter->setPen(m_pen); painter->drawImage(HighlightRectItem::ImgPosition, HighlightRectItem::scaleBoximg); //painter->begin(&boximg); painter->drawRect(rect()); //painter->end(); }
In these way I can paint on scene multiple rect (and insert it on QList and QGraphicsItemGroup for fourter implements ) and my custom class with the image .... Now when move the image over a rect I can relase the image and it go in the same pos of background rect .... at this point I would like the rect in the background receives the image of the rect you can move .... I have the point of anchor but I'm not able using it to send a signal to gui .... I have the QList but how can get the list number when movable image is over it?
regards
Giorgio -
Hi,
Do you mean some sort of drag and drop where the image contained in the "dropped" item is copied into the drop area which is your other item ?
-
Hi,
Do you mean some sort of drag and drop where the image contained in the "dropped" item is copied into the drop area which is your other item ?
-
Then you should take a look at the drag and drop robot example.
-
Then you should take a look at the drag and drop robot example.
@SGaist the example sho me the better usage of mouse event and mimedata.... but in my case not helph me.
In robot example robot is composed by multiple class item ..... headitem receive qimage... other only qcolour... in my case the item that receive qimage is generated from while do statement.... so I not know the item quontity at first time.So for do that i try to subclass qgraphicsscenes for manage mouse event in scene..... but this crash my app. In my subclass mouse event void there is nothing..... only empty void ... but these crash the app. If cancel mouse event reimplement void the crash disappear. Why?
An other strategy is using qlist<qgraphicsobject *> and graphicsscene chenge item signal for detect mouse pos in scene.... use ->contains macro for detect in whitch item is the mouse signal and than paint a new item in scene..... but is not elegant way to do the things.
Other better way?
Regards
Giorgio -
Weren't you trying to just copy the image from one graphics object inside another ? Or did I misunderstood ?
-
Weren't you trying to just copy the image from one graphics object inside another ? Or did I misunderstood ?
@SGaist said in QGraphicsItem copy inside QGraphicScenes:
Weren't you trying to just copy the image from one graphics object inside another
Yes is right, but robot example:
for (int i = 0; i < 10; ++i) { ColorItem *item = new ColorItem; item->setPos(::sin((i * 6.28) / 10.0) * 150, ::cos((i * 6.28) / 10.0) * 150); scene.addItem(item); } Robot *robot = new Robot; robot->setTransform(QTransform::fromScale(1.2, 1.2), true); robot->setPos(0, -20); scene.addItem(robot);
my case:
for (int i = 0; i < user_choose_these_number; ++i) { Robot *robot = new Robot; robot->setPos(calculationPos); scene.addItem(robot); } ColorItem *item = new ColorItem; ColorItem->addQImage /*static image, but resized from user gui*/ /*coloritem is moveable in my case see my code above... ColorItem = HighlightRectItem in my case*/ bla bla bla....
so is the inverse situation ..... robot can't select mimetype pos .... coloritem must select it ... and robot & coloritem isn't QObject (no signal slot).
Actually I create a new class to work with
HighlightRectItem::getPoint(QPointF myPointBox)
for emit a signal every time the user select new position of QImage show in HighlightRectItem..... I hope these work
regards
Giorgio -
The points are not related to drag and drop, they are just there to position stuff around the scene.
AFAIU, you should only have one type of item that you can drag and that you can drop on. I proposed the example as a way to learn how to create mime data and use it from a DnD point of view in your scene. Not as a replacement of what you are doing.
-
The points are not related to drag and drop, they are just there to position stuff around the scene.
AFAIU, you should only have one type of item that you can drag and that you can drop on. I proposed the example as a way to learn how to create mime data and use it from a DnD point of view in your scene. Not as a replacement of what you are doing.
@SGaist said in QGraphicsItem copy inside QGraphicScenes:
AFAIU ... what is means?? Sorry I'm not english ...
I proposed the example as a way to learn how to create mime data and use it
thanks a lot for these ... and I try use mime but is not possible because multiple element ... so now I try to make some type of signal send from my class .... that's all. I hope not to be rude .... unfortunately the English is not my preferred language.
regards
Giorgio -
In order to make a clean solutio I have subcalss my GraphicsScene and reimplement mouserelease event ... in these way I can grab mouse pos in scene at release .... I add
QVector<QRectF> for insert the box area in number choose from user .... after mouse release event in manwindow run these void:void MainWindow::testpos(QPointF testpoint) { if((ui->VBox_2->isOn) && !BoxVectV.empty()) { for ( int ibox = 0; ibox != BoxVectV.size(); ibox++) { if(BoxVectV[ibox].contains(testpoint.x(), testpoint.y())) { //QImage itmbximage = MainWindow::bxV.scaled(int(RealBoxSizeXX/4), int(RealBoxSizeYY/4) , Qt::IgnoreAspectRatio);*/ QPainter *itmbxpaint; itmbxpaint->drawImage(MainWindow::bxV_scal_pos.x(), MainWindow::bxV_scal_pos.y(), MainWindow::bxV_scal); QRectF tmpRect(BoxVectV[ibox].toRect()); QGraphicsRectItem *itmbx = new QGraphicsRectItem(); /* in these way crash app*/ itmbx->setRect(tmpRect); itmbx->setPos(tmpRect.topLeft()); itmbx->paint(itmbxpaint, 0, 0); scene_Pallet->addItem(itmbx); /*QGraphicsPixmapItem* item = new QGraphicsPixmapItem(); /* in these way not happen in grapicsscene .... is because z index?? item->setPixmap(QPixmap::fromImage(MainWindow::bxV_scal)); item->setPos(tmpRect.topLeft()); scene_Pallet->addItem(item);*/ //ibox = BoxVectV.size(); qDebug() << "this point image:...." << tmpRect.topLeft(); break; } } } if((ui->HBox_2->isOn) && !BoxVectH.empty()) { for ( int ibox = 0; ibox != BoxVectH.size(); ibox++) { if(BoxVectH[ibox].contains(testpoint.x(), testpoint.y())) { qDebug() << "this point:...." << testpoint; } } } }
debug show me the right info after every mouse release event ... but I'm not able to show my image (declare as static because I use it in other part of my app ...)
The image is ok ... if show it in other pos for example it show correct ...regards
giorgio -
In order to make a clean solutio I have subcalss my GraphicsScene and reimplement mouserelease event ... in these way I can grab mouse pos in scene at release .... I add
QVector<QRectF> for insert the box area in number choose from user .... after mouse release event in manwindow run these void:void MainWindow::testpos(QPointF testpoint) { if((ui->VBox_2->isOn) && !BoxVectV.empty()) { for ( int ibox = 0; ibox != BoxVectV.size(); ibox++) { if(BoxVectV[ibox].contains(testpoint.x(), testpoint.y())) { //QImage itmbximage = MainWindow::bxV.scaled(int(RealBoxSizeXX/4), int(RealBoxSizeYY/4) , Qt::IgnoreAspectRatio);*/ QPainter *itmbxpaint; itmbxpaint->drawImage(MainWindow::bxV_scal_pos.x(), MainWindow::bxV_scal_pos.y(), MainWindow::bxV_scal); QRectF tmpRect(BoxVectV[ibox].toRect()); QGraphicsRectItem *itmbx = new QGraphicsRectItem(); /* in these way crash app*/ itmbx->setRect(tmpRect); itmbx->setPos(tmpRect.topLeft()); itmbx->paint(itmbxpaint, 0, 0); scene_Pallet->addItem(itmbx); /*QGraphicsPixmapItem* item = new QGraphicsPixmapItem(); /* in these way not happen in grapicsscene .... is because z index?? item->setPixmap(QPixmap::fromImage(MainWindow::bxV_scal)); item->setPos(tmpRect.topLeft()); scene_Pallet->addItem(item);*/ //ibox = BoxVectV.size(); qDebug() << "this point image:...." << tmpRect.topLeft(); break; } } } if((ui->HBox_2->isOn) && !BoxVectH.empty()) { for ( int ibox = 0; ibox != BoxVectH.size(); ibox++) { if(BoxVectH[ibox].contains(testpoint.x(), testpoint.y())) { qDebug() << "this point:...." << testpoint; } } } }
debug show me the right info after every mouse release event ... but I'm not able to show my image (declare as static because I use it in other part of my app ...)
The image is ok ... if show it in other pos for example it show correct ...regards
giorgio@gfxx UPDATE : ... there are for shure z index problem .... now it work ... but not very fine.
/*why these way to show image crash the app??*/ QPainter *itmbxpaint; itmbxpaint->drawImage(MainWindow::bxV_scal_pos.x(), MainWindow::bxV_scal_pos.y(), MainWindow::bxV_scal); QRectF tmpRect(BoxVectV[ibox].toRect()); QGraphicsRectItem *itmbx = new QGraphicsRectItem(); itmbx->setRect(tmpRect); itmbx->setPos(tmpRect.topLeft()); itmbx->paint(itmbxpaint, 0, 0); scene_Pallet->addItem(itmbx); /* how to add z index??*/
regards
Giorgio