As you know, only QObject-based classes can have signals or slots. My initial idea was to make a QObject class to hold the value of the variable you want to monitor, and override some of the basic functions, something like this (untested code!):
class MonitoredValue
: public QObject{
Q_OBJECT;
public:
MonitoredValue
( const uint32_t
& initialVal,
QObject * parent
= 0 ) : QObject( parent
), monitoredVal
( initialVal
) {} virtual ~MonitoredVal() {}
// read-only access
const uint32_t & operator() const { return monitoredVal; }
uint32_t & operator() const { return monitoredVal; }
// assignment
const MonitoredValue & operator=( const uint32_t & newVal )
{ emit valueChanging( monitoredVal ); monitoredVal = newVal; emit valueChanged( monitoredVal ); return *this; }
const MonitoredValue & operator=( const MonitoredValue & rhs )
{ emit valueChanging( monitoredVal ); monitoredVal = rhs.monitoredVal; emit valueChanged( monitoredVal ); return *this; }
// cast operators
operator uint32_t & () { return monitoredVal; }
operator const uint32_t & () const { return monitoredVal; }
signals:
void valueChanging( const uint32_t & val );
void valueChanged( const uint32_t & val );
private:
uint32_t monitoredVal;
};
class MonitoredValue : public QObject
{
Q_OBJECT;
public:
MonitoredValue( const uint32_t & initialVal, QObject * parent = 0 ) : QObject( parent ), monitoredVal( initialVal ) {}
virtual ~MonitoredVal() {}
// read-only access
const uint32_t & operator() const { return monitoredVal; }
uint32_t & operator() const { return monitoredVal; }
// assignment
const MonitoredValue & operator=( const uint32_t & newVal )
{ emit valueChanging( monitoredVal ); monitoredVal = newVal; emit valueChanged( monitoredVal ); return *this; }
const MonitoredValue & operator=( const MonitoredValue & rhs )
{ emit valueChanging( monitoredVal ); monitoredVal = rhs.monitoredVal; emit valueChanged( monitoredVal ); return *this; }
// cast operators
operator uint32_t & () { return monitoredVal; }
operator const uint32_t & () const { return monitoredVal; }
signals:
void valueChanging( const uint32_t & val );
void valueChanged( const uint32_t & val );
private:
uint32_t monitoredVal;
};
To copy to clipboard, switch view to plain text mode
Example:
using ErrorWord = MonitoredValue;
ErrorWord errorWord( 0 );
connect( &errorWord, &ErrorWord::valueChanging, this, &MyClass::errorChanging );
connect( &errorWord, &ErrorWord::valueChanged, this, &MyClass::errorChanged );
uint32_t currentError = errorWord;
errorWord = 42; // assigns new error, emits signals;
using ErrorWord = MonitoredValue;
ErrorWord errorWord( 0 );
connect( &errorWord, &ErrorWord::valueChanging, this, &MyClass::errorChanging );
connect( &errorWord, &ErrorWord::valueChanged, this, &MyClass::errorChanged );
uint32_t currentError = errorWord;
errorWord = 42; // assigns new error, emits signals;
To copy to clipboard, switch view to plain text mode
It would be nice if you could create this as a template, so that the monitored value could be any type, but Qt doesn't permit that for QObject classes. It would also be nice if you could connect any member function of a class to a slot, but as far as I can tell, the signal / slot mechanism requires that the class emitting the signal be derived from QObject.
And because Qt also doesn't support copy constructors or assignment operators for QObject classes, this method may not work without some modification.
You can also use other signal / slot mechanisms, like Boost Signals2. This might work better for your purpose than Qt's version.
Bookmarks