Go back to Richel Bilderbeek's homepage.

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






(C++) Qt QGraphicsProxyWidget example 5


QGraphicsProxyWidget example 5 is a QGraphicsProxyWidget example.


The final goal is to be able to move the MyItem, even when MyItem has a focusable QLineEdit. This example is the first step in reaching this goal. This is accomplished by letting the original QWidget emit a signal on a mouse press. The QGraphicsView looks up the QGraphicsProxyWidget corresponding to the MyItem and let it follow the mouse cursor. Note that the QLineEdit is disabled: when enabling it, after the first time focus is given to a QLineEdit, it never releases it. Yet...







Technical facts


Application type(s)

Operating system(s) or programming environment(s)


Project type:

C++ standard:


Libraries used:






Qt project file: CppQGraphicsProxyWidgetExample5.pro


QT       += core
QT       += gui
QMAKE_CXXFLAGS += -Wextra -Werror -std=c++11
TARGET = CppQGraphicsProxyWidgetExample5
CONFIG   += console
CONFIG   -= app_bundle
SOURCES += main.cpp








#include <cassert>
#include <cmath>
#include <QApplication>
#include <QDesktopWidget>
#include <QGraphicsProxyWidget>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QLineEdit>
#include <QLabel>
#include <QVBoxLayout>
#include <QDialog>
#include <QGraphicsSceneMouseEvent>
#include <boost/signals2.hpp>

struct MyItem : public QWidget
  MyItem(QWidget *parent = 0, Qt::WindowFlags f = 0)
    : QWidget(parent,f),
      m_edit(new QLineEdit(this)),
      m_label(new QLabel(this))
    QVBoxLayout * const layout = new QVBoxLayout(this);
  QLineEdit * const m_edit;
  QLabel * const m_label;
  boost::signals2::signal<void (MyItem*)> m_signal_mouse_press;
  void mousePressEvent(QMouseEvent * event)

struct MyView : public QGraphicsView
  MyView(QWidget *parent = 0)
    : QGraphicsView(parent),
      m_scene(new QGraphicsScene(this)),

    //Create the QLineEdit instances
    const int sz = 10;
    std::vector<QGraphicsProxyWidget *> proxies;
    for (int i=0; i!=sz; ++i)
      MyItem * const item = new MyItem;
      item->m_label->setText(QString("#") + QString::number(i));
      item->m_edit->setText(QString("Text ") + QString::number(i));
          this,_1)); //_1 because the signal contains an argument
      //Add the QWidget and obtain its proxy
      QGraphicsProxyWidget * const proxy = m_scene->addWidget(item);
      m_m[item] = proxy;

    const double ray = 200.0; //pixels
    for (int i=0; i!=sz; ++i)
      const double angle = 2.0 * M_PI * static_cast<double>(i) / static_cast<double>(sz);
      const int x = static_cast<int>(0.0 + (std::sin(angle) * ray));
      const int y = static_cast<int>(0.0 - (std::cos(angle) * ray));
      QGraphicsProxyWidget * const proxy = proxies[i];
      proxy->setRotation(angle * 360.0 / (2.0 * M_PI));
      proxy->setFlag(QGraphicsItem::ItemIsMovable,true); //No need to set this flag
  //My own added method
  void OnMousePress(MyItem * item)
    m_drag_item = item;
  void mouseMoveEvent(QMouseEvent *event)
    if (m_drag_item)
      //Convert the position clicked to the QGraphicsView coordinat
      QPointF p = this->mapToScene(event->pos());
      //Let the
  void mouseReleaseEvent(QMouseEvent *)
    m_drag_item = nullptr;
  QGraphicsScene * const m_scene;
  MyItem * m_drag_item;
  std::map<MyItem *,QGraphicsProxyWidget *> m_m;

int main(int argc, char **argv)
  //Create the application
  QApplication app(argc, argv);
  MyView view;
    //Put the dialog in the screen center
    const QRect screen = QApplication::desktop()->screenGeometry();
    view.move( screen.center() - view.rect().center() );
  return app.exec();






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