Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) QGraphicsPixmapItemExample7

 

QGraphicsPixmapItem example example 7: respond to cursor moving over pixmap while holding the cursor still is a QGraphicsPixmapItem example. This example shows how to let the QGraphicsView responds to the cursor being moved over the QGraphicsPixmapItem, where the pixmap keeps responding even when the mouse cursor is held still.

 

 

QGraphicsPixmapItem example 6: let the view respond to cursor moving over pixmap is the predecessor of QGraphicsPixmapItem example 7: respond to cursor moving over pixmap while holding the cursor still.

Technical facts

 

Application type(s)

Operating system(s) or programming environment(s)

IDE(s):

Project type:

C++ standard:

Compiler(s):

Libraries used:

 

 

 

 

 

Qt project file: ./CppQGraphicsPixmapItemExample7/CppQGraphicsPixmapItemExample7.pro

 

exists (../../DesktopApplication.pri) {
  include(../../DesktopApplication.pri)
}
!exists (../../DesktopApplication.pri) {
  QT += core printsupport
  QT += gui
  greaterThan(QT_MAJOR_VERSION, 4): QT += widgets svg
  CONFIG   += console
  CONFIG   -= app_bundle
  TEMPLATE = app
  CONFIG(release, debug|release) {
    DEFINES += NDEBUG NTRACE_BILDERBIKKEL
  }
  QMAKE_CXXFLAGS += -std=c++11 -Wall -Wextra -Weffc++
  unix {
    QMAKE_CXXFLAGS += -Werror
  }
}

exists(../../Libraries/Boost.pri) {
  include(../../Libraries/Boost.pri)
}
!exists(../../Libraries/Boost.pri) {
  win32 {
    INCLUDEPATH += \
      ../../Libraries/boost_1_55_0
  }
}

SOURCES += \
    qtmain.cpp \
    qtwidget.cpp \
    qtitem.cpp \
    qthighlighter.cpp

HEADERS += \
    qtwidget.h \
    qtitem.h \
    qthighlighter.h

RESOURCES += \
    CppQGraphicsPixmapItemExample7.qrc

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qthighlighter.h

 

#ifndef QTHIGHLIGHTER_H
#define QTHIGHLIGHTER_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <QObject>
#pragma GCC diagnostic pop

struct QGraphicsItem;
struct QTimer;

class QtHighlighter : public QObject
{
  Q_OBJECT

public:
  QtHighlighter(QObject *parent = 0);

  ///Set the item to highlight.
  ///If set with a nullptr, highlighting the current item stops
  ///If set with the same item twice, nothing new happens
  void SetItem(QGraphicsItem * const item);


private:
  ///The item being highlighted
  QGraphicsItem * m_item;

  ///The timer used for highlighting every 100 ms
  QTimer * const m_timer;


private slots:
  void OnTimer();
};

#endif // QTHIGHLIGHTER_H

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qthighlighter.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <QGraphicsItem>
#include <QTimer>
#include "qthighlighter.h"
#pragma GCC diagnostic pop

QtHighlighter::QtHighlighter(QObject *parent)
  : QObject(parent),
    m_item(nullptr),
    m_timer(new QTimer(this))
{
  m_timer->setInterval(10); //ms
  QObject::connect(
    m_timer,SIGNAL(timeout()),
    this,SLOT(OnTimer()));
}

void QtHighlighter::SetItem(QGraphicsItem * const item)
{
  m_item = item;
  if (m_item)
  {
    this->m_timer->start();
  }
  else
  {
    this->m_timer->stop();
  }
}


void QtHighlighter::OnTimer()
{
  if (m_item)
  {
    m_item->setRotation(m_item->rotation() + 5.0);
  }
}

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qtitem.h

 

#ifndef QTITEM_H
#define QTITEM_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <QGraphicsPixmapItem>
#pragma GCC diagnostic pop

///A QGraphicsPixmapItem that loads its pixmap from resources
///and is clickable
struct QtItem : public QGraphicsPixmapItem
{
  QtItem(QGraphicsItem *parent = 0);

  protected:
  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

#endif // QTITEM_H

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qtitem.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <cassert>
#include <QCursor>
#include <QPainter>
#include "qtitem.h"
#pragma GCC diagnostic pop

QtItem::QtItem(QGraphicsItem *parent)
  : QGraphicsPixmapItem(parent)
{
  assert(this->pixmap().isNull()
    && "Assume no pixmap loaded yet");

  //Load the pixmap from resources
  this->setPixmap(QPixmap(":/images/PicR.png"));

  assert(!this->pixmap().isNull()
    && "Assume pixmap is loaded successfully");

  //Let the item have (0.0,0.0) as its center,
  //so it will remain in place when rotating
  this->setOffset(-pixmap().rect().center());

  this->setFlags(
      QGraphicsItem::ItemIsMovable
    | QGraphicsItem::ItemIsSelectable);

}

void QtItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
  //Let QGraphicsPixmapItem handle most of the painting
  QGraphicsPixmapItem::paint(painter,option,widget);

  //Draw a thick red line around the pixmap when it is selected
  if (this->isSelected())
  {
    painter->setPen(QPen(QColor(255,0,0),3));
    painter->drawRoundedRect(this->boundingRect().adjusted(3.0,3.0,-3.0,-3.0),6.0,6.0);
  }
}

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qtmain.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <QApplication>
#include "qtwidget.h"
#pragma GCC diagnostic pop

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  QtWidget w;
  w.setGeometry(100,100,400,400);
  w.show();
  return a.exec();
}

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qtwidget.h

 

#ifndef QTWIDGET_H
#define QTWIDGET_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <QGraphicsView>
#pragma GCC diagnostic pop

///Forward declaration
struct QtHighlighter;

struct QtWidget : public QGraphicsView
{
  QtWidget();

  protected:
  void mouseMoveEvent(QMouseEvent *event);

  private:
  ///Class highlighting a QGraphicsItem
  QtHighlighter * const m_highlighter;
};

#endif // QTWIDGET_H

 

 

 

 

 

./CppQGraphicsPixmapItemExample7/qtwidget.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <cassert>
#include <iostream>

#include <boost/bind.hpp>
#include <boost/lambda/bind.hpp>

#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QMouseEvent>

#include "qthighlighter.h"
#include "qtitem.h"
#include "qtwidget.h"
#pragma GCC diagnostic pop

QtWidget::QtWidget()
  : m_highlighter(new QtHighlighter(this))
{
  QGraphicsScene * const scene = new QGraphicsScene(this);
  this->setScene(scene);
  const int n_items = 8;
  for (int i=0; i!=n_items; ++i)
  {
    QtItem * const item = new QtItem;
    //Scatter those items around a bit
    item->setPos(
      - 128 + (std::rand() % 256),
      - 128 + (std::rand() % 256));

    scene->addItem(item);
  }

  ///Without this line, mouseMoveEvent will not be called
  this->setMouseTracking(true);
}

void QtWidget::mouseMoveEvent(QMouseEvent *event)
{
  //Rotate the first item found under the cursor
  {
    //Find the items under the cursor
    QList<QGraphicsItem *> all_items = this->scene()->items();
    std::vector<QGraphicsItem *> items; //The items under the cursor
    const QPointF pos = this->mapToScene(event->pos());

    std::for_each(all_items.begin(),all_items.end(),
      [this,&items,pos](QGraphicsItem * item)
      {
        const QRectF rect = item->boundingRect().translated(item->pos());
        if (rect.contains(pos))
        {
          items.push_back(item);
        }
      }
    );
    //Rotate the possible first item found
    if (!items.empty())
    {
      m_highlighter->SetItem(items[0]);
    }
    else
    {
      m_highlighter->SetItem(nullptr);
    }
  }

  //Let QGraphicsView handle the default mouseMoveEvents, for example
  //the moving of the items
  QGraphicsView::mouseMoveEvent(event);
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml