Реклама

Qt/C++ - Урок 023. Перетаскивание QGraphicsItem на QGraphicsScene мышью

TutorialQtQGraphicsScene, Qt, Qt урок, перетаскивание, QGraphicsItem377

Допустим, что вы делаете приложение, которое будет отображать на графической сцене элементы сетевой инфраструктуры. Вопрос в том, как сделать перемещение этих элементов мышью, то есть осуществлять перетаскивание элементов. Иными словами брать элемент мышью и осуществлять его перемещение в другое место графической сцены.

Давайте разберёмся, как это сделать.

Структура проекта

Для демонстрации примера создаём новый проект и добавляем в него новый класс, отнаследованный от QGraphicsItem .

  • MoveGraphicsItem.pro - профайл проекта;
  • main.cpp - запускающий файл;
  • widget.h - заголовочный файл главного окна;
  • widget.cpp - файл исходных кодов главного окна;
  • moveitem.h - заголовочный файл графического элемента;
  • moveitem.cpp - файл исходных кодов графического элемента.
  • widget.ui - форма главного окна.

widget.ui

В форму главного окна помещаем два объекта:

  • QGraphicsView - будет содержать графическую сцену;
  • QPushButton - будет создавать новые графические объекты.
Главное окно

widget.h

В заголовочном файле главного окна лишь объявляем графическую сцену и слот для кнопки.

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QGraphicsScene>

#include <moveitem.h>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QGraphicsScene *scene;
};

#endif // WIDGET_H

widget.cpp

В данном файле осуществляем косметическую настройку приложения - это касается конструктора класса. И производим создание графических объектов, которые будем перетаскивать на графической сцене. При этом объекты при создании располагаются в произвольном порядке.

#include "widget.h"
#include "ui_widget.h"

/* Функция для получения рандомного числа
 * в диапазоне от минимального до максимального
 * */
static int randomBetween(int low, int high)
{
    return (qrand() % ((high + 1) - low) + low);
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // Косметическая подготовка приложения
    this->resize(640,640);          // Устанавливаем размеры окна приложения
    this->setFixedSize(640,640);

    scene = new QGraphicsScene(this);   // Инициализируем графическую сцену
    scene->setItemIndexMethod(QGraphicsScene::NoIndex); // настраиваем индексацию элементов

    ui->graphicsView->resize(600,600);  // Устанавливаем размер graphicsView
    ui->graphicsView->setScene(scene);  // Устанавливаем графическую сцену в graphicsView
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);    // Настраиваем рендер
    ui->graphicsView->setCacheMode(QGraphicsView::CacheBackground); // Кэш фона
    ui->graphicsView->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);

    scene->setSceneRect(0,0,500,500); // Устанавливаем размер сцены
}

Widget::~Widget()
{
    delete ui;
}

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

moveitem.h

Для осуществления красивого перетаскивания графических объектов Нам понадобится использовать функции mouseMoveEvent , mousePressEvent и mouseReleaseEvent . В функции mouseMoveEvent будет производиться непосредственное перетаскивание графического объекта, а в двух других будет производиться смена внешнего вида курсора мыши, которые будет сигнализировать о том, что мы берём и отпускаем графический объект.

#ifndef MOVEITEM_H
#define MOVEITEM_H

#include <QObject>
#include <QGraphicsItem>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QCursor>

class MoveItem : public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    explicit MoveItem(QObject *parent = 0);
    ~MoveItem();

signals:

private:
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

public slots:
};

#endif // MOVEITEM_H

moveitem.cpp

Графический объект будет представлять собой обычный зеленый квадрат.

#include "moveitem.h"

MoveItem::MoveItem(QObject *parent) :
    QObject(parent), QGraphicsItem()
{

}

MoveItem::~MoveItem()
{

}

QRectF MoveItem::boundingRect() const
{
    return QRectF (-30,-30,60,60);
}

void MoveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::black);
    painter->setBrush(Qt::green);
    painter->drawRect(-30,-30,60,60);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

void MoveItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    /* Устанавливаем позицию графического элемента
     * в графической сцене, транслировав координаты
     * курсора внутри графического элемента
     * в координатную систему графической сцены
     * */
    this->setPos(mapToScene(event->pos()));
}

void MoveItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    /* При нажатии мышью на графический элемент
     * заменяем курсор на руку, которая держит этот элемента
     * */
    this->setCursor(QCursor(Qt::ClosedHandCursor));
    Q_UNUSED(event);
}

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

Итог - осуществляем перетаскивание

В результате у Вас должно получиться приложение, в котором по нажатию кнопки динамически создаваться зелёный квадрат в случайном месте графической сцены. И Вы сможете осуществлять его перетаскивание при помощи мыши.

Демонстрацию работы приложения Вы можете увидеть в видеоуроке.

Ссылка на скачивание проекта в zip-архиве: MoveGraphicsItem

Видеоурок

@EVILEG 7 октября 2015 г. 21:26

Реклама

Реклама

Комментарии

Комментарии

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

Реклама

Реклама