0

I am having a difficulty in understanding qwt oscilloscope example. i understand most of the program roughly, but i can not find the linkage between samplingthread class and plot class.

It seems like chart samples are from samplingthread and it is provided to QwtPlotCurve object in plot class.

However i can not find linkage between samplingthread object and plot object. But when i change the frequency value in samplingthread object, it is applied and appears on plot object (canvas).

Below is part of code (from main.cpp) i do not really understood but please reference full project (need decompress i think) by downloading from http://sourceforge.net/projects/qwt/files/qwt/6.1.2/.

int main( int argc, char **argv )
{
QApplication app( argc, argv );
app.setPalette( Qt::darkGray );

MainWindow window;
window.resize( 800, 400 );

SamplingThread samplingThread;
samplingThread.setFrequency( window.frequency() ); // window.frequency()'s type is double 
samplingThread.setAmplitude( window.amplitude() ); // window.amplitude()'s type is double
samplingThread.setInterval( window.signalInterval() ); // window.signalInterval()'s type is double

window.connect( &window, SIGNAL( frequencyChanged( double ) ),
    &samplingThread, SLOT( setFrequency( double ) ) );
window.connect( &window, SIGNAL( amplitudeChanged( double ) ),
    &samplingThread, SLOT( setAmplitude( double ) ) );
window.connect( &window, SIGNAL( signalIntervalChanged( double ) ),
    &samplingThread, SLOT( setInterval( double ) ) );

window.show();

samplingThread.start();
window.start();

bool ok = app.exec();

samplingThread.stop();
samplingThread.wait( 1000 );

return ok;
}

above's window.start() is equal to plot->start(). and i can not find the linkage between plot object and samplingthread object. Can anyone explain this part for me?

Jackson
  • 17
  • 5
  • those `window.connect` are signals and slots being connected to later transfer data between the components. If you are not familiar with the mechanism it is like setting callbacks. – UmNyobe Dec 14 '15 at 13:13
  • The signals are from qwt widgets located in MainWindows, and it is link to samplingThread's function. My question is linkage between plot and samplingThread. Because when samplingThread's member variables (e.g. frequency) value changed it is applied and shown up on plot. – Jackson Dec 14 '15 at 13:21
  • so yu mean the other way `thread -> UI`? This code doesnt shown anything useful. – UmNyobe Dec 14 '15 at 13:27
  • you can download full project from the link i posted. and at the end of question i wrote "window.start() is equal to plot->start()" If you see the code above again you will find "samplingThread.start(); window.start();" Two objects call their own start function but i can not find the linkage between objects. – Jackson Dec 14 '15 at 13:32

2 Answers2

2

signal/slot between 2 threads ends up as QEvents in the Qt event queue. Considering, that the sampling thread creates values very fast ( f.e every 10ms ) it is obvious, that this is no option.

So there needs to be a shared buffer, where writing/reading is guarded by a mutex - this is what SignalData is.

The bridge between SignalData and the curve is done by CurveData, that implements a given API. If you like you could compare CurveData with the idea of QAbstractItemModel.

But the oscilloscope application is more a demo than an example. It shows what is possible with very low CPU usage ( runs nicely even on the Pi with reasonable CPU usage ) with using a couple of tricks.

Uwe
  • 705
  • 3
  • 3
0

There is a use of a curious singleton pattern based on the class SignalData. First of all, the singleton :

class CurveData: public QwtSeriesData<QPointF>
{
public:
    const SignalData &values() const;
    SignalData &values();
...
};

const SignalData &CurveData::values() const
{
    return SignalData::instance();
}

QPointF CurveData::sample( size_t i ) const
{
    return SignalData::instance().value( i );
}

On one side

Plot::Plot( QWidget *parent ):
{
    d_curve = new QwtPlotCurve();
    ...
    d_curve->setData( new CurveData() ); //singleton being used inside each curvedata
    ...
}

And on the other

void SamplingThread::sample( double elapsed )
{
    if ( d_frequency > 0.0 )
    {
        const QPointF s( elapsed, value( elapsed ) );
        SignalData::instance().append( s ); //singleton being used
    }
}

I'll refrain from using this example as it is.

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
  • thanks for checking out the code. All i want is the linkage between SamplingThread and plot object that we talked about alot. Can you find and explain it in detail for me? – Jackson Dec 14 '15 at 14:36
  • @Jackson it is still not clear because I forgot to add a piece of the code. There is a SignalData hidden with a signeton which does all the magic. Where they too lazy to use signals or shared objects? No idea. – UmNyobe Dec 14 '15 at 14:45