PDA

View Full Version : How to execute a QProgressDialog once



franco.amato
16th March 2010, 14:19
Hi to all,
I created a QProgressDialog to inform the user about waveform generation.
The problem is that everytime the widget is repainted ( for example with a resize event ) the waveform is re-calculated and the QProgressDialog
is shown. I would display that progress dialog only the first time that I display the waveform.

Is there a way to do that? How can such dialog can be disabled?

Regards

wysota
16th March 2010, 14:25
Please show us your current code.

franco.amato
16th March 2010, 14:36
Please show us your current code.

Here it go


/************************************************** **********************/
/* drawStandardPCM16 */
/************************************************** **********************/
void WaveDisplay::drawStandardPCM16( QPainter& painter, int numSamples )
{
int h = height();
int w = width();

// Calculate magical constants that should be left untouched unless dealing with
// other variants of PCM-Streams.
int channels = m_wave->getChannels();
int bits = m_wave->getBits();
int pcm_length = m_wave->getPcmLength();
int freq = m_wave->getFrequency();

int sample_size = channels * bits / 8;

int samples = pcm_length / sample_size; //pcm_length bytes totali del sound
int maxHeight = (h / 2) / channels;
int increment = (h / 2);
float modifier = (float)maxHeight / 0x0000FFFF * 2;
int* minValues = new int[channels];
int* maxValues = new int[channels];

//Adjust these values to obtain a different drawing scheme. Offset defines the initial sample
//where to begin drawing (it takes into account channel, sample size, bit size etc). maxSamplesOnscreen
//defines the amount of samples displayed on the screen.
int startOffset = 0;
int maxSamplesOnscreen = samples;

// Calculate the starting position in the stream where start fetching our data. And calculate
// the width between samples. By default the width truncated to the nearest integer for drawing.
// Note: doubles are needed for this calculation due floating point in-precision. Floating point
// operations have the same speed either so it's quite valid.
char* stream = (char*)m_wave->getSoundStream() + (startOffset * sample_size);
double samplesInc = 1.0f / ( maxSamplesOnscreen / (double)w);
double samplesCur = 0.0f;

//Correct the maximum samples displayed on the screen, if this step is not done we'ld be
//drawing outside the boundaries of the data stream.
maxSamplesOnscreen = (samples - startOffset) > maxSamplesOnscreen ? maxSamplesOnscreen : (samples - startOffset);

QProgressDialog *progress = new QProgressDialog("Creating waveform...",
"Abort process", 0, maxSamplesOnscreen, this);
progress->setWindowModality(Qt::WindowModal);

//Iterate over each sample that lies withing the lower and upper boundaries that we precomputed. For
//every sample we draw the maximum value, and minimum value. Store the value in a temp. array and process that
//array once we detect our x is changed.
for( int i = startOffset, maxI = i + maxSamplesOnscreen, oldX = 0, x = 0; i < maxI; i++, stream += sample_size, samplesCur += samplesInc, x = samplesCur)
{
if( i % (60 * freq) == 0 ) //every minute
{
m_timePosition.append(i);// qua dovrei anche aggiungere i minuti, magari con una map
}
//Analyze the raw stream of data to determine the min and max amplitude of the sound.
for( int k = 0, j = 0; k < channels; k++, j += 2 )
{
signed short* value1 = reinterpret_cast<signed short*>(stream + j);
int y = *value1 * modifier;
maxValues[k] = y > maxValues[k] ? y : maxValues[k];
minValues[k] = y < minValues[k] ? y : minValues[k];
}

//Early out of x is the same
if( oldX == x)
continue;
oldX = x;
progress->setValue(i);

//Draw the peaks from midpoint to upper peak, and from midpoint to lower peaks
for( int k = 0, startY = maxHeight; k < channels; k++ )
{
QPoint midPoint = QPoint(x, startY);
painter.drawLine( midPoint, QPoint(x, startY + maxValues[k]) );
painter.drawLine( midPoint, QPoint(x, startY + minValues[k]) );
maxValues[k] = minValues[k] = 0;
startY += increment;
}
}
progress->setValue( maxSamplesOnscreen );
progress->deleteLater();

//Draw a mid-based line for each channel around, so there is always 'signal displayed' used against
//double point in-precision.
for( int k = 0, startY = maxHeight; k < channels; k++ )
{
painter.drawLine( QPoint(0, startY), QPoint(w, startY) );
startY += increment;
}

//Clean up the outline tables for min and max values.
delete minValues;
delete maxValues;
}

wysota
16th March 2010, 14:47
Why not have a boolean variable which will say whether this wave form has been calculated before and show the dialog only when it is set to false (and set it to true after showing the dialog)?

franco.amato
16th March 2010, 16:36
Why not have a boolean variable which will say whether this wave form has been calculated before and show the dialog only when it is set to false (and set it to true after showing the dialog)?

This can be an idea. But I have to hide all code of the qprogressdialog inside the boolean check? Or only a part?