13 июня 2019 г. 2:05

Рисование в QGraphicsScene, как выделить объект

Добрый день.
Рисую в QGraphicsScene мышкой, ниже код сцены (сделан на основе урока).
В Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью описан вариант перетаскивания. Скажите пожалуйста как можно подключить этот вариант перетаскивания к описаному варианту рисования?
h

#ifndef PAINTSCENE_H
#define PAINTSCENE_H

#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include "QGraphicsView"
#include <QTimer>
#include <QDebug>
//#include "QLabel"
//#include "QPainter"




class paintScene : public QGraphicsScene
{

    Q_OBJECT

public:
    explicit paintScene(QObject *parent = 0);
    ~paintScene();
    QPen myPen;
    //переменная для режима рисования или перепещения с удалением
    QString paintOrDelete = "рисовать"; //"удалять, перетаскивать"

    //QGraphicsView *myQGraphicsScene;
    //paintScene *scene;  // Объявляем кастомную графическую сцену
    //QPainter test
    //QPainter myPainter;

    //int x,y;
    //void paintEvent(QPaintEvent *event);


private:
    QPointF     previousPoint;      // Координаты предыдущей точки
    bool buttonIsPressed;

private:
    // Для векторного рисования используем события мыши
    //временно срыл рисование векторной графики
    void mousePressEvent(QGraphicsSceneMouseEvent * event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

};

#endif // PAINTSCENE_H

cpp

#include "paintscene.h"


paintScene::paintScene(QObject *parent) : QGraphicsScene(parent)
{
    //myQGraphicsScene = new QGraphicsView();
    //scene = new paintScene();       // Инициализируем графическую сцену

    //Pen
    myPen.setWidth(20);
    myPen.setColor(Qt::green);
    //myPen.setColor(QColor(255, 0, 0, 10));
    myPen.setCapStyle(Qt::RoundCap);
    myPen.setStyle(Qt::SolidLine);

}

paintScene::~paintScene()
{

}

void paintScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (paintOrDelete == "рисовать")
    {
        // При нажатии кнопки мыши отрисовываем эллипс
        addEllipse(event->scenePos().x() -  myPen.width()/2,
                   event->scenePos().y() -  myPen.width()/2,
                   myPen.width(),
                   myPen.width(),
                   QPen(Qt::NoPen),
                   QBrush(myPen.color()));
        // Сохраняем координаты точки нажатия
        previousPoint = event->scenePos();
        buttonIsPressed = true;


        //для рисования попиксельно
        //x = event->scenePos().x();
        //y = event->scenePos().x();
    }
    /*if (paintOrDelete == "удалять, перетаскивать")
    {
        /* При нажатии мышью на графический элемент
         * заменяем курсор на руку, которая держит этот элемента
         * */
        /*this->setCursor(QCursor(Qt::ClosedHandCursor));
        Q_UNUSED(event);

        //удаление правой кнопкой мыши
        if (QApplication::mouseButtons() == Qt::RightButton)
        {
            this->deleteLater();
        }
    }*/
}

void paintScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    //if (paintOrDelete == "рисовать")
    {
        if (buttonIsPressed)
        {
            // Отрисовываем линии с использованием предыдущей координаты
            addLine(previousPoint.x(),
                    previousPoint.y(),
                    event->scenePos().x(),
                    event->scenePos().y(),
                    myPen);
            // Обновляем данные о предыдущей координате
            previousPoint = event->scenePos();
        }
    }
    /*if (paintOrDelete == "удалять, перетаскивать")
    {
        /* Устанавливаем позицию графического элемента
         * в графической сцене, транслировав координаты
         * курсора внутри графического элемента
         * в координатную систему графической сцены
         * */
        /*this->setPos(mapToScene(event->pos()));
    }*/
}

void paintScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    buttonIsPressed = false;
    /*if (paintOrDelete == "удалять, перетаскивать")
    {
        /* При отпускании мышью элемента
         * заменяем на обычный курсор стрелку
         * */
        /*this->setCursor(QCursor(Qt::ArrowCursor));
        Q_UNUSED(event);
    }*/
}

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
3

Дорбрый день.

К этому варианту с графической сценой лучше тот код вообще не прикручивать. Вы видите разницу меджу вашим кодом и кодом в примере?

В примере предлагается переопределить класс QGraphicsItem, а вы хотите прикрутить тот код к графической сцене. Вы только так усложните себе жизнь.

По факту, вам нужно заменить добавление линий, которое вы делаете через addLine, на методы addItem. И добавлять через метод addItem кастомный класс графической линии, в котором будет реализовано перемещении объектов, как было показано в той статье.

Либо устанавливать флаг перемещаемости для графического объекта. Возможно, что вам такого хватит

void Widget::on_pushButton_clicked()
{
    MoveItem *item = new MoveItem();        // Создаём графический элемент
    item->setPos(randomBetween(30, 470),    // Устанавливаем случайную позицию элемента
                 randomBetween(30, 470));

    item->setFlag(QGraphicsItem::ItemIsMovable); // делаем элемент перемещаемым

    scene->addItem(item);   // Добавляем элемент на графическую сцену
}

Скажите пожалуйста, как его в таком случае перемещать и удалять?

Обычно я этот

 MoveItem *item

помещаю в вектор std::vector m_items; потом по сигналам нажатия выдёргиваю из веторов и удаляю. Есть пример удаления в одном из уроков по написанию игры

Смотрите слот для удаления яблок.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Ищу работу?
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы

e
14 октября 2019 г. 14:59
erina_m

C++ - Тест 003. Условия и циклы

  • Результат:78баллов,
  • Очки рейтинга2
S
14 октября 2019 г. 4:09
Sergey1985

C++ - Тест 001. Первая программа и типы данных

  • Результат:80баллов,
  • Очки рейтинга4
AM
12 октября 2019 г. 17:24
Arshak Martirosyan

C++ - Тест 001. Первая программа и типы данных

  • Результат:66баллов,
  • Очки рейтинга-1
Последние комментарии
14 октября 2019 г. 7:48
Евгений Легоцкой

Добрый день. Нет, если сами по себе координаты при ресайзе все подсчитываются правильно, то это уже проблема графической подсистемы в ОС и работы с X11, если вы конечно под Linux собирали проект…
m
13 октября 2019 г. 9:17
magrif

Здравствуйте. Сделал подобным образом ресайз и в Qt Widgets, и в QML. Везде получаю, что при изменении размера через левую или верхннюю границы проихсодит мерцание подобно как на этом виде…
6 октября 2019 г. 13:44
Евгений Легоцкой

Может база не открылась в прошлый раз. Либо пересобрали проект. хз, если честно ))
s
6 октября 2019 г. 11:27
sander-007

Добрый день Евгений. Спасибо за пример, все понятно. Попытался сделать по аналогии сохранение в базе MySQL заготовок отчетов excel, но MySQL ругается на нарушение в строке запроса. Я подозреваю,…
30 сентября 2019 г. 3:33
Евгений Легоцкой

Если честно то с авторизацией в мобильном приложении я не работал. Знаю, что для таких вещей используют батарейку Django Rest Framework, с помощью которого можно получить токена для самого сайта…
Сейчас обсуждают на форуме
14 октября 2019 г. 14:51
Евгений Легоцкой

Добрый день. Первое, что приходит на ум, то можно подружить это дело через веб сокеты. Со стороны Django - это использование батарейки django-channels, а со стороны это QtWebSockets. …
11 октября 2019 г. 3:11
Евгений Легоцкой

Понятно. Мне нужен пример вашего кода с проблемой. Если сможете накидать вырезку из вашего проекта, которую можно будет скомпилировать и посмотреть, что там происходит, то попробую помочь. Но бы…
t
10 октября 2019 г. 10:58
tantrido

Вот ответ на мой вопрос: https://doc.qt.io/qt-5/qtvirtualkeyboard-deployment-guide.html#creating-inputpanel The input panel must be a sibling element next to the application conta…
9 октября 2019 г. 15:45
Евгений Легоцкой

Добрый день. Нет, я таким не сталкивался, но вот таким образом вы можете разбить тот тег, на ноды, и забрать текст в нормально порядке, а потом вам уже не составит труда, как я думаю, запи…
9 октября 2019 г. 12:04
Вадим Полшков

Здравствуйте. Все получилось, только редирект сделал по другому redirect(price.file.url) Спасибо вам за помощь!
EVILEG
О нас
Услуги
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB