Qt Graphical Objects & Multi-Thread
WidgetUpdate.hpp
Go to the documentation of this file.
1 // Qt Graphical Objects & Multi-Thread
2 
49 #ifndef QT_WIDGET_UPDATE
50 #define QT_WIDGET_UPDATE
51 
52 #include <math.h> // to get sqrt declaration
53 #include <iostream> // to get std::cout declaration
54 #include <QWidget>
55 #include <QThread>
56 
57 #ifdef BUGGY
58 class UpdateWidget; // UpdateWidget declaration
59 #endif
60 
65 class Updater : public QThread {
66 #ifndef BUGGY
67  Q_OBJECT // This macro is needed for the signal to get handled
68 #else
69  UpdateWidget& widget;
70 #endif
71 
73 
75  void run();
76 
77 public:
79 #ifdef BUGGY
80  Updater(UpdateWidget& parent) : widget(parent),
82 #else
83  Updater() :
84 #endif
85  still_running(false) { start(); }
86 
88  void stop() {
89  still_running = false; // ask to the run() method to stop
90  wait(); // when stopped, returns
91  }
92 
93 #ifndef BUGGY
94 Q_SIGNALS:
97  void updatePosRequest(const int dist);
98 #endif
99 }; // end of class Updater
100 
101 
106 class UpdateWidget : public QWidget {
107  Q_OBJECT // This macro is needed to handle connect methods
108 
109  QPoint position;
110  QPoint aimed;
112 
117  QRect region(const QPoint& pos, const bool big = false) const {
118  static const int offset = 2 + (big ? 5 : 0);
119  return QRect(pos, pos).adjusted(-offset, -offset, offset, offset);
120  }
121 
125  void modify(QPoint& variable, const QPoint& value) {
126  // region modified in the drawing (union of two increased regions)
127  const QRect change = region(variable, true)
128  | region(value, true);
129  // !!!Bug in Qt 4: remaining stains even whith increased regions!!!
130  variable = value; // update the variable
131  /* std::cout << "Update from thread "
132  << QThread::currentThreadId() << std::endl; */
133  update(change); // update the drawing
134  // !!!Feature: Qt crashes (SegV) at high frequency!!!
135  // Everything seems fine with update() (but more expensive)...
136  }
137 
138 #ifdef BUGGY
139 public Q_SLOTS:
140 #else
141 private Q_SLOTS:
142 #endif
143  void updatePosition(const int dist) {
147  const QPointF new_pos = position, vector = new_pos - aimed;
148  const qreal x = vector.x(), y = vector.y(),
149  distance = sqrt(x * x + y * y);
150  if (distance > 1e-6)
151  modify( position, (new_pos - vector * dist /
152  distance).toPoint() );
153  }
154 
155 public:
158  UpdateWidget(QWidget* parent = 0)
159  : QWidget(parent),
160 #ifdef BUGGY
161  updater(*this)
162 #else
163  updater()
164 #endif
165  {
166  setBackgroundRole(QPalette::Base);
167 #ifndef BUGGY
168  connect( &updater, SIGNAL( updatePosRequest(const int) ),
169  this, SLOT( updatePosition(const int) ) );
170 #endif
171  }
172 
174  ~UpdateWidget() { updater.stop(); }
175 
177  void init() {
178  const QPoint center(width() / 2, height() / 2);
179  modify(position, center);
180  modify(aimed, center); /*
181  std::cout << "Main thread " << QThread::currentThreadId()
182  << std::endl; */
183  }
184 
185 protected:
189  void paintEvent(QPaintEvent *event);
190 
194  void mouseMoveEvent(QMouseEvent *event);
195 
196 }; // end of class UpdateWidget
197 
198 #endif // QT_WIDGET_UPDATE
void modify(QPoint &variable, const QPoint &value)
Memorizes a new value in a variable and redraw.
bool still_running
Should the thread continue to run?
This widget draws two positions, one moved by drag and drop, the other moved by a separate thread tow...
This separated thread updates regularly the position drawn towards the aimed one, either directly (if...
void stop()
Stops the thread.
~UpdateWidget()
The desctructor stops the thread.
Updater()
The thread&#39;s constructor.
UpdateWidget(QWidget *parent=0)
The widget&#39;s constructor.
QRect region(const QPoint &pos, const bool big=false) const
Returns the graphical region drawn around the position.
QPoint aimed
The aimed position, also drawn in the widget.
QPoint position
The position drawn in the widget.
void init()
Initialises both points.
void updatePosRequest(const int dist)
Sends a signal to ask for an update of the widget.
void run()
The main method of this thread.
Updater updater
The thread updating the position.