Михаиллл
July 18, 2019, 6:19 p.m.

Как удалять 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
The question is asked by the articleQt/C++ - Lesson 023. Moving QGraphicsItem on QGraphicsScene with mouse help

Do you like it? Share on social networks!

13
Pavel K.
  • July 19, 2019, 12:56 p.m.
  • (edited)

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

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

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

    Михаиллл
    • July 19, 2019, 8:52 p.m.

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

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

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

      Михаиллл
      • July 20, 2019, 6:44 p.m.
      • (edited)

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

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

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

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

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

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

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

        Михаиллл
        • July 20, 2019, 7:31 p.m.

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

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

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

          Pavel K.
          • July 20, 2019, 7:53 p.m.
          • (edited)

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

          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.
            • July 20, 2019, 7:58 p.m.

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

              Михаиллл
              • July 20, 2019, 8:50 p.m.

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

                Pavel K.
                • July 20, 2019, 9:03 p.m.
                • (edited)

                С гуглом не дружите :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. }
                  Михаиллл
                  • July 20, 2019, 9:11 p.m.

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

                    Михаиллл
                    • July 21, 2019, 2:03 p.m.

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

                      Evgenii Legotckoi
                      • July 21, 2019, 4:07 p.m.

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

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

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

                        Михаиллл
                        • July 21, 2019, 7:30 p.m.

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

                          Evgenii Legotckoi
                          • July 22, 2019, 1:01 p.m.

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

                            Comments

                            Only authorized users can post comments.
                            Please, Log in or Sign up
                            • Last comments
                            • AK
                              April 1, 2025, 11:41 a.m.
                              Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
                            • Evgenii Legotckoi
                              March 9, 2025, 9:02 p.m.
                              К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
                            • VP
                              March 9, 2025, 4:14 p.m.
                              Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
                            • ИМ
                              Nov. 22, 2024, 9:51 p.m.
                              Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                            • Evgenii Legotckoi
                              Oct. 31, 2024, 11:37 p.m.
                              Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup