Михаиллл
18 июля 2019 г. 18:19

Как удалять QGraphicsItem попавшие в определенную область на QGraphicsScene

Добрый день.
В этой статье описывается перетаскивание объектов QGraphicsItem , также можно их удалять кодом, описанным ниже.
Но как сделать так, что объект будет удаляться, если при отпускании кнопки мыши, он окажется в определенной области на QGraphicsScene?

  1. void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
  2. {
  3. /* При нажатии мышью на графический элемент
  4. * заменяем курсор на руку, которая держит этот элемента
  5. * */
  6. this->setCursor(QCursor(Qt::ClosedHandCursor));
  7. Q_UNUSED(event);
  8.  
  9. //удаление правой кнопкой мыши
  10. if (QApplication::mouseButtons() == Qt::RightButton)
  11. {
  12. qDebug()<<"delete";
  13. this->deleteLater();
  14. }
  15. qDebug()<<"MoveItem";
  16. }
3
Вопрос задан по статьеQt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

Вам это нравится? Поделитесь в социальных сетях!

13
Pavel K.
  • 19 июля 2019 г. 12:56
  • (ред.)

пропиши состояние обьекта , что -то типо

  1. if(item.y = yAxis && item.x = xAxis) {
  2. this->deleteLater();
  3. }

(надеюсь суть ты уловил)

    Михаиллл
    • 19 июля 2019 г. 20:52

    Суть понятна, но не понятно где и как это использовать.
    Как я понимаю для начала нужно получить координату на поле и находящийся эллемент на этой координате в этой части кода

    1. void MoveItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    2. {
    3. /* При отпускании мышью элемента
    4. * заменяем на обычный курсор стрелку
    5. * */
    6. this->setCursor(QCursor(Qt::ArrowCursor));
    7. Q_UNUSED(event);
    8. qDebug()<<"MoveItem";
    9. }

    Сккажите пожалуйста, как это можно сделать?

      Михаиллл
      • 20 июля 2019 г. 18:44
      • (ред.)

      Попробовал сделать так, координаты смещения выдает

      1. qDebug()<<"position:"<<event->pos();

      А если так, то показывает координаты относительно монитора

      1. qDebug()<<"position:"<<event->screenPos();

      Пробовал так, но так в левой верхней части выдает минусы

      1. qDebug()<<"position:"<<event->scenePos();

      Скажите пожалуйста как получить относительно графической сцены?

        Михаиллл
        • 20 июля 2019 г. 19:31

        Если не считать касяк с неверным отображением координат, так работает

        1. if (event->scenePos().x() > 200
        2. && event->scenePos().x() < 300
        3. && event->scenePos().y() > 200
        4. && event->scenePos().y() < 300)

        Может быть Вы знаете, почему к сцене добавили по 60 пикселей сверху и слева?

          Pavel K.
          • 20 июля 2019 г. 19:53
          • (ред.)

          Извини что долго , вот

          1. #include "moveitem.h"
          2.  
          3. MoveItem::MoveItem(QObject *parent) :
          4. QObject(parent), QGraphicsItem()
          5. {
          6.  
          7. }
          8.  
          9. MoveItem::~MoveItem()
          10. {
          11.  
          12. }
          13.  
          14. QRectF MoveItem::boundingRect() const
          15. {
          16. QRectF item = *new QRectF;
          17. item.setCoords(-30,-30,60,60);
          18. return item;
          19. }
          20.  
          21. void MoveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
          22. {
          23. painter->setPen(Qt::black);
          24. painter->setBrush(Qt::green);
          25. painter->drawRect(-30,-30,60,60);
          26.  
          27.  
          28. Q_UNUSED(option);
          29. Q_UNUSED(widget);
          30. }
          31.  
          32. void MoveItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
          33. {
          34.  
          35. this->setPos(mapToScene(event->pos()));
          36. // ...чтобы за границы родителя не выходил квадратик
          37. if (x() < 0)
          38. setPos(0, y());
          39. else if (x() > 300)
          40. setPos(300, y());
          41.  
          42. if (y() < 0)
          43. setPos(x(), 0);
          44. else if (y() > 300)
          45. setPos(x(), 300);
          46.  
          47. }
          48. bool MoveItem::checkCoordinates(qreal &_x,qreal &_y)
          49. {
          50. // 0.0 0.0 - левый верхний угол, когда туда перемещаешь квадратик - он удаляется
          51. if( _x == 0.0 && _y == 0.0){
          52. return true;
          53. } else {
          54. return false;
          55. }
          56. }
          57. void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
          58. {
          59. /* При нажатии мышью на графический элемент
          60. * заменяем курсор на руку, которая держит этот элемента
          61. * */
          62. this->setCursor(QCursor(Qt::ClosedHandCursor));
          63. Q_UNUSED(event);
          64.  
          65. qreal tempX,tempY;
          66. tempX = this->pos().x();
          67. tempY = this->pos().y();
          68. if (QApplication::mouseButtons() == Qt::RightButton || checkCoordinates(tempX,tempY))
          69. {
          70. this->deleteLater();
          71. }
          72. }
          73.  
          74. void MoveItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
          75. {
          76. /* При отпускании мышью элемента
          77. * заменяем на обычный курсор стрелку
          78. * */
          79. this->setCursor(QCursor(Qt::ArrowCursor));
          80. Q_UNUSED(event);
          81. }
          82.  
            Pavel K.
            • 20 июля 2019 г. 19:58

            я с графическими элементами не работал , поэтому точно не скажу что за 60 пикселей.

              Михаиллл
              • 20 июля 2019 г. 20:50

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

                Pavel K.
                • 20 июля 2019 г. 21:03
                • (ред.)

                С гуглом не дружите :D ?

                1. #include <QGraphicsPixmapItem>
                2. #include <QFileDialog>
                3. //- - - - - - - - - -
                4. //-----widget.cpp ---
                5. // - - - - - - - - - -
                6.  
                7. void Widget::on_pushButton_clicked()
                8. {
                9. // MoveItem *item = new MoveItem(); // Создаём графический элемент
                10. // Добавляем элемент на графическую сцену
                11. QString fileNamez = QFileDialog::getOpenFileName(this,"Choose Picture","C:/");
                12. QGraphicsPixmapItem *pm = scene->addPixmap( QPixmap(fileNamez) );
                13. pm->setPos(0,0);
                14.  
                15. }
                  Михаиллл
                  • 20 июля 2019 г. 21:11

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

                    Михаиллл
                    • 21 июля 2019 г. 14:03

                    Может быть смещение сцены на 60 связанно с нарисованным 4-х угольником?

                      Evgenii Legotckoi
                      • 21 июля 2019 г. 16:07

                      Если вы про этот метод

                      1. QRectF MoveItem::boundingRect() const
                      2. {
                      3. return QRectF (-30,-30,60,60);
                      4. }

                      То мне нужно было, чтобы координата (0,0) была по центру квадрата в его локальной системе координат, тогда метод setPos устанавливает позицию квадрата на графической сцене ровно по центру квадрата. то есть его локальный (0,0) будет лежать например в координате (200,200) при установке позиции через setPos

                        Михаиллл
                        • 21 июля 2019 г. 19:30

                        Понятно. Но может ли этот метот объяснить появления 60 пинусовых пикселей по обоим координатам?

                          Evgenii Legotckoi
                          • 22 июля 2019 г. 13:01

                          Я отрисовываю квадрат в его локальной системе координат от верхнего левого угла (-30,-30) до его правого нижнего угла (30,30).
                          Поэтому мне нужно указать размеры объекта через boundingRect(), в локальной системе координат объекта.
                          То есть от координаты (-30,-30) при высоте 60 и ширине 60. Поэтому и получается QRectF (-30,-30,60,60);

                            Комментарии

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