Go back to Richel Bilderbeek's homepage.

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

 

 

 

 

 

(C++) QtExample29

 

QtQt CreatorLubuntu

 

Qt example 29: bouncing balls widget is a Qt Example that uses QGraphicsView to create a simple widget in which the items (ellipses) respond to collision with others.

 

 

 

 

 

Downloads

 

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: ./CppQtExample29/CppQtExample29.pro

 

exists(../../DesktopApplication.pri) {
  include(../../DesktopApplication.pri)
}
!exists(../../DesktopApplication.pri) {
  QT += core gui
  greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  TEMPLATE = app

  CONFIG(debug, debug|release) {
    message(Debug mode)
  }

  CONFIG(release, debug|release) {
    message(Release mode)
    DEFINES += NDEBUG NTRACE_BILDERBIKKEL
  }

  QMAKE_CXXFLAGS += -std=c++11 -Wall -Wextra

  unix {
    QMAKE_CXXFLAGS += -Werror
  }
}

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

SOURCES += \
    qttooltestbouncingballswidgetmaindialog.cpp \
    qtmain.cpp \
    qtbouncingballswidget.cpp \
    qtbouncingball.cpp
HEADERS  += \
    qttooltestbouncingballswidgetmaindialog.h \
    qtbouncingballswidget.h \
    qtbouncingball.h
FORMS    += qttooltestbouncingballswidgetmaindialog.ui

 

 

 

 

 

./CppQtExample29/qtbouncingball.h

 

#ifndef QTBOUNCINGBALL_H
#define QTBOUNCINGBALL_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QGraphicsItem>
#pragma GCC diagnostic pop

struct QGraphicsScene;

struct QtBouncingRect : public QGraphicsItem
{
  QtBouncingRect(QGraphicsItem *parent, QGraphicsScene *scene);

  ///Make the balls move
  void advance(int phase);

  ///Thanks compiler for reminding me to add this member function!
  QRectF boundingRect() const;

  ///The real collision shape
  QPainterPath shape() const;

  ///Thanks compiler for reminding me to add this member function!
  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);


  private:
  ///Use simplified physics in this example
  ///Horizontal speed (delta x)
  double m_dx;

  ///Use simplified physics in this example
  ///Vertical speed (delta y)
  double m_dy;

  ///The scene this class is in
  QGraphicsScene * const m_scene;
};

#endif // QTBOUNCINGBALL_H

 

 

 

 

 

./CppQtExample29/qtbouncingball.cpp

 

#include <cassert>
#include <cmath>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QList>
#include <QPainter>
#include "qtbouncingball.h"
#pragma GCC diagnostic pop

QtBouncingRect::QtBouncingRect(QGraphicsItem *parent, QGraphicsScene *scene)
: QGraphicsItem(parent),
   m_dx(1.0), m_dy(1.0), m_scene(scene)
{
  assert(m_scene && "An initialized QGraphicsScene must be supplied");
  m_scene->addItem(this);
}

void QtBouncingRect::advance(int /* phase */)
{
  if (x() + m_dx + (boundingRect().width() * 0.5) > m_scene->width()) m_dx = -std::abs(m_dx);
  else if (x() + m_dx - (boundingRect().width() * 0.5) < 0.0) m_dx = std::abs(m_dx);
  if (y() + m_dy + (boundingRect().height() * 0.5) > m_scene->height()) m_dy = -std::abs(m_dy);
  else if (y() + m_dy - (boundingRect().width() * 0.5) < 0.0) m_dy = std::abs(m_dy);
  this->setPos(x() + m_dx, y() + m_dy);

  //Respond to collision with other item
  const QList<QGraphicsItem *> others = collidingItems();
  if (others.isEmpty()) return;
  const QGraphicsItem * const other = others[0];
  if (this->x() < other->x()) m_dx = -std::abs(m_dx);
  else if (this->x() > other->x()) m_dx =  std::abs(m_dx);
  if (this->y() < other->y()) m_dy = -std::abs(m_dy);
  else if (this->y() > other->y()) m_dy =  std::abs(m_dy);
  this->setPos(x() + m_dx, y() + m_dy);
  this->setPos(x() + m_dx, y() + m_dy);

}

QRectF QtBouncingRect::boundingRect() const
{
  return QRectF(-16.0,-16.0,32.0,32.0);
}

void QtBouncingRect::paint(
  QPainter *painter,
  const QStyleOptionGraphicsItem * /* option */,
  QWidget * /* widget */)
{
  painter->drawEllipse(this->boundingRect());
}

QPainterPath QtBouncingRect::shape() const
{
  QPainterPath p;
  p.addEllipse(boundingRect());
  return p;
}

 

 

 

 

 

./CppQtExample29/qtbouncingballswidget.h

 

#ifndef QTBOUNCINGBALLSWIDGET_H
#define QTBOUNCINGBALLSWIDGET_H

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

struct QGraphicsScene;

struct QtBouncingRectsWidget : public QGraphicsView
{
  QtBouncingRectsWidget(QWidget *parent = 0);


  protected:
  void resizeEvent(QResizeEvent *event);

  private:
  QGraphicsScene * const m_scene;
};

#endif // QTBOUNCINGBALLSWIDGET_H

 

 

 

 

 

./CppQtExample29/qtbouncingballswidget.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QTimer>
#include <QGraphicsScene>
#include "qtbouncingball.h"
#include "qtbouncingballswidget.h"
#pragma GCC diagnostic pop

QtBouncingRectsWidget::QtBouncingRectsWidget(QWidget *parent)
  : QGraphicsView(parent),
    m_scene(new QGraphicsScene(this->rect(),this))
{
  this->setScene(m_scene);

  for (int i=0; i!=3; ++i)
  {
    QtBouncingRect * const ball = new QtBouncingRect(0,m_scene);
    ball->setPos(
      static_cast<double>((i - 1) * 32) + (0.5 * static_cast<double>(width())),
      static_cast<double>((i - 1) * 32) + (0.5 * static_cast<double>(height())));
  }

  {
    QTimer * const timer = new QTimer(this);
    QObject::connect(timer,SIGNAL(timeout()),m_scene,SLOT(advance()));
    timer->setInterval(20);
    timer->start();
  }

  //Turn off the scrollbars, as they look ugly
  this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}


void QtBouncingRectsWidget::resizeEvent(QResizeEvent *)
{
  m_scene->setSceneRect(this->rect());
}

 

 

 

 

 

./CppQtExample29/qtmain.cpp

 

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

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

 

 

 

 

 

./CppQtExample29/qttooltestbouncingballswidgetmaindialog.h

 

#ifndef QTTOOLTESTBOUNCINGBALLSWIDGETMAINDIALOG_H
#define QTTOOLTESTBOUNCINGBALLSWIDGETMAINDIALOG_H

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <QDialog>
#pragma GCC diagnostic pop

namespace Ui {
class QtToolTestBouncingBallsWidgetMainDialog;
}

class QtToolTestBouncingBallsWidgetMainDialog : public QDialog
{
    Q_OBJECT
    
public:
  explicit QtToolTestBouncingBallsWidgetMainDialog(QWidget *parent = 0);
  QtToolTestBouncingBallsWidgetMainDialog(const QtToolTestBouncingBallsWidgetMainDialog&) = delete;
  QtToolTestBouncingBallsWidgetMainDialog& operator=(const QtToolTestBouncingBallsWidgetMainDialog&) = delete;
  ~QtToolTestBouncingBallsWidgetMainDialog();
    
private:
  Ui::QtToolTestBouncingBallsWidgetMainDialog *ui;
};

#endif // QTTOOLTESTBOUNCINGBALLSWIDGETMAINDIALOG_H

 

 

 

 

 

./CppQtExample29/qttooltestbouncingballswidgetmaindialog.cpp

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include "qtbouncingballswidget.h"
#include "qttooltestbouncingballswidgetmaindialog.h"
#include "ui_qttooltestbouncingballswidgetmaindialog.h"
#pragma GCC diagnostic pop

QtToolTestBouncingBallsWidgetMainDialog::QtToolTestBouncingBallsWidgetMainDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QtToolTestBouncingBallsWidgetMainDialog)
{
  ui->setupUi(this);
  ui->layout->addWidget(new QtBouncingRectsWidget(this));
}

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

 

 

 

 

 

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