Реклама

Qt/C++ - Урок 018. QGraphicsItem - наследование и СЛОТы

QGraphicsItem, QGraphicsItem example, QGraphicsItem Qt, QGraphicsItem слот, Qt, множественное наследование

А теперь поговорим немного о наследовании от QGraphicsItem и применении системы СИГНАЛ ов и СЛОТ ов при взаимодействии с графическими объектами на графической сцене QGraphicsScene. В задачу данного урока входит создание приложения, в котором на графической сцене будет отображаться объект класса QGraphicsItem , по нажатию на который будет появляться диалоговое окно QMessageBox , сигнализирующее о событии нажатия на графический объект.

Программный код был написан в QtCreator 3.3.1 на основе Qt 5.4.1.

Структура проекта для работы с QGraphicsItem

В структура данного проекта входят:

  • TestPoint.pro - профайл проекта;
  • mainwindow.h - заголовочный файл основного окна приложения;
  • mainwindow.cpp - файл исходных кодов основного окна приложения;
  • mypoint.h - заголовочный код класса, отнаследованного от QGraphicsItem;
  • mypoint.cpp - соответственно исходный код;
  • main.cpp - основной файл, с которого стартует приложение, в уроке не рассматривается, поскольку создаётся по умолчанию;
  • mainwindow.ui - файл дизайна главного окна.

mainwindow.ui

Вся работа с этим файлом заключается в том, что мы кидаем виджет QGraphicsView в центра главного окна и растягиваем его по ширине и высоте окна.

mainwindow.h

Файл примечателен лишь объявлением графической сцены, нашего нового класса MyPoint и СЛОТа для обработки СИГНАЛа из MyPoint.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QMessageBox>

#include <mypoint.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow  *ui;
    /* Объявляем графическую сцену и Точку с которой будем работать */
    QGraphicsScene  *scene;
    MyPoint         *point;

private slots:
    /* Слот для обработки сигнала из точки */
    void slotFromPoint();
};

#endif // MAINWINDOW_H

mainwindow.cpp

Здесь уже поинтереснее. В данном файле выполняем реализацию СЛОТа, а также подключаем это СЛОТ к объекту класса MyPoint. А также добавляем данный объект на графическую сцену.

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    /* Инициализируем графическую сцену с точку с которой будем работать */
    scene = new QGraphicsScene();
    point = new MyPoint();

    /* Подключаем сигнал из точки к СЛОТу в главном классе */
    connect(point,SIGNAL(signal1()),this, SLOT(slotFromPoint()));

    /* Устанавливаем графическую сцену в виджет */
    ui->graphicsView->setScene(scene);
    scene->addItem(point);  // И добавляем на сцену точку
}

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

void MainWindow::slotFromPoint()
{
    QMessageBox::information(this,
                             "Зафиксировано нажатие",
                             "Вы нажали на точку!!!"
                             "\n"
                             "\n"
                             "\n      С Уважением, Ваш КЭП!!!");
}

mypoint.h

Ключевым моментом в данном файле является то, что в данном классе применено множественное наследование, а именно то, что Мы отнаследовались не только от QGraphicsItem, но и от QObject. Дело в том, что если не наследоваться от QObject, то СИНГАЛы и СЛОТы не будут работать и проект не скомпилируется, если вы будете применять функцию connect для подключения СИГНАЛа из MyPoint, к СЛОТу в MainWindow.

#ifndef MYPOINT_H
#define MYPOINT_H

#include <QObject>
#include <QGraphicsItem>
#include <QPainter>

/* Чтобы работали СЛОТЫ и СИГНАЛЫ, наследуемся от QOBJECT,
 * */
class MyPoint : public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    explicit MyPoint(QObject *parent = 0);
    ~MyPoint();

signals:
    /* Сигнал, который будет посылаться в том случае,
     * если произошел клик мышью по объекту
     * */
    void signal1();

protected:
    /* Перегружаем метод нажатия мышью, для его перехвата
     * */
    void mousePressEvent(QGraphicsSceneMouseEvent *event);

private:
    /* Данные методы виртуальные, поэтому их необходимо реализовать
     * в случае наследования от QGraphicsItem
     * */
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

#endif // MYPOINT_H

mypoint.cpp

Самое главное, на что рекомендую обратить внимание в данном классе, так это на то, что мы переопределяем метод для вызова события нажатия на графический объект правой кнопкой мыши. И вызываем в данном методе СИГНАЛ.

#include "mypoint.h"

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

}

MyPoint::~MyPoint()
{

}

QRectF MyPoint::boundingRect() const
{
    /* возвращаем координаты расположения точки
     * по ним будет определяться нажатие точки
     * */
    return QRectF(0,0,100,100);
}

void MyPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    // Устанавливаем кисть в QPainter и отрисовываем круг, то есть ТОЧКУ
    painter->setBrush(Qt::black);
    painter->drawEllipse(QRectF(0, 0, 100, 100));
        Q_UNUSED(option);
        Q_UNUSED(widget);
}

/* Переопределив метод перехвата события нажатия кнопки мыши,
 * добавляем посылку СИГНАЛА от объекта
 * */
void MyPoint::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    emit signal1();
    // Вызываем родительскую функцию события нажатия кнопки мыши
    QGraphicsItem::mousePressEvent(event);
}

Итог

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

Видеоурок

Реклама

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
  • BlinCT
  • 22 октября 2017 г. 12:46

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

  • Результат 64 баллов
  • Очки рейтинга -1
  • Kiops
  • 22 октября 2017 г. 3:56

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

  • Результат 86 баллов
  • Очки рейтинга 6
  • Kiops
  • 22 октября 2017 г. 2:41

Qt - Тест 001. Сигналы и слоты

  • Результат 100 баллов
  • Очки рейтинга 10
Последние комментарии
  • EVILEG
  • 21 октября 2017 г. 3:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

Добавил архив с проектом

  • EVILEG
  • 20 октября 2017 г. 20:06

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

После работы поищу, должен где-то быть на винте.

  • Миша
  • 20 октября 2017 г. 20:04

Qt/C++ - Урок 031. QCustomPlot - строим график по времени

не могли бы вы выложить архив с рабочей версией скрипта?

  • EVILEG
  • 20 октября 2017 г. 20:03

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Использование дизайнера в Qt Creator и использование ui файлов является распространённой практикой в Qt фреймворке. Написать отдельную статью про то, что это такое? - может быть. Опи...

  • Миша
  • 20 октября 2017 г. 19:43

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

Но почему вы это не описали? Не могли бы вы описать.

Сейчас обсуждают на форуме
  • EVILEG
  • 22 октября 2017 г. 12:05

Закрепление якорей в момент создания объекта через JS

Добрый день! Якоря - это не те свойства, которые можно устанавливать сразу по инициализации, лучше их править после создания объекта, поскольку при одновременной установке они могут в...

  • EVILEG
  • 21 октября 2017 г. 23:33

Создание истории редактирования постов на сайте

Ясно. Тогда я лучше не буду тратить время на его проверку. Тем более, что я использую гугловский prettyprint для подсветки кода. Спасибо за информацию.

QFile::copy() возвращает false

Получилось! Спасибо огромное! path1 = "C:/Users/555/Pictures/00GAF13AP001-002.jpg"true

  • cordsac
  • 19 октября 2017 г. 15:49

How can I select the QGraphicView Item and change the properties

Ok I'll check it sir,If you can please do article(tutorial) about this,Its really useful.Thank you if you can give me some sample code when you free.thanks again

  • cordsac
  • 17 октября 2017 г. 19:28

How can I open SVG file through QT

Okay,Thank you sir :)