PDA

View Full Version : Customize tick labels in a QwtSlider



RomanRdgz
6th September 2012, 07:51
I'm using QwtSlide to represent some values. For example if I want to represent 500, 1500, 2500... 9500, I'm getting a slider drawn from 500 to 9500, but labels appear only in 100, 2000, ... 9000.

Code:


ui.timeSampleSlider->setScale(500, 9500, 1000);
ui.timeSampleSlider->setRange(500, 9500, 1000);
ui.timeSampleSlider->setValue(500);
ui.timeSampleSlider->setEnabled(true);


Looks like this:
8190

I want all my possible values (500, 1500, ... , 9500) to be labeled instead of these. I also tried this:



QList<double> ticks [3];
ticks[0]<<0.5<<1.5<<2.5<<3.5<<4.5<<5.5<<6.5<<7.5<<8.5<<9.5;
QwtScaleDiv fixedScale(QwtInterval(start, end), ticks);
QwtScaleDraw* scaleDraw = new QwtScaleDraw();
scaleDraw->setScaleDiv(fixedScale);
ui.timeSampleSlider->setScaleDraw(scaleDraw);
ui.timeSampleSlider->setRange(start, end, interval);
ui.timeSampleSlider->setValue(start);
ui.timeSampleSlider->setEnabled(true);


And looks even worse:
8191

Any idea?

Uwe
6th September 2012, 09:15
Why setting a tick at 0.5 when you want to have one at 500 ?

Uwe

PS: you can use QwtSlider::setScale( const QwtScaleDiv & )

RomanRdgz
6th September 2012, 09:22
Why setting a tick at 0.5 when you want to have one at 500 ?

Because it represents time, and I work with milliseconds and want labels to look as seconds. Anyway that's a different issue I'll try to solve next. This is what happens when you inherit code :(


PS: you can use QwtSlider::setScale( const QwtScaleDiv & )

Anyway, what would be the difference with the setScaleDraw I tried? Could you give an example of usage? Thanks

Uwe
6th September 2012, 12:37
Because it represents time, and I work with milliseconds and want labels to look as seconds.
Then set the ticks to 500, 1000 and modify how the tick labels are represented:


virtual QwtText YourScaleDraw::label( double value ) const
{
return QwtScaleDraw::label( value / 1000.0 );
}

HTH,
Uwe

RomanRdgz
6th September 2012, 12:44
That could work to control what's written into each label. I am overriding a method from Qt. Is it OK if I declare this overriden method into my own code, or do I need to do anything special?

Anyway I still don't know how to tell the QwtSlider where to put labels, only how to format them. How can I do that?

Uwe
6th September 2012, 17:43
Usually it's done this way:

ui.timeSampleSlider->setScale( 500, 9500, 500 );
ui.timeSampleSlider->setRange( 500, 9500 );
ui.timeSampleSlider->setScaleMaxMinor( 0 ); // when you want to disable the minor ticks
Of course you can also calculate and assign the ticks manually ( even if I don't see any good reason in your situation ) using a QwtScaleDiv object, but then code has to be like this:


QList< double > ticks[ QwtScaleDiv::NTickTypes ];
ticks[ QwtScaleDiv::MajorTick ] << 500 << 1000 << 1500 << ... << 8000 << 8500 << 9000 << 9500;

ui.timeSampleSliders->setScale( QwtScaleDiv( 500, 9500, ticks ) );
ui.timeSampleSlider->setRange( 500, 9500 );
Uwe

RomanRdgz
7th September 2012, 07:53
But I have already tried the first code (but with 1000 between each tick, not 500 as you write here), and I'm getting the slide I put an image about, with ticks on 1000, 2000, 3000, ... 9000, when my selectable points are in 500, 1500, 2500, ... 9500. I still don't know how to solve that.

Uwe
7th September 2012, 08:19
By replacing 1000 by 500 - or if you want to have the ticks on 500, 1500 only ( but not on 1000 ) the second option I have posted ( of course without the ticks at 1000, 2000 ... ) is what you need.

Uwe

RomanRdgz
7th September 2012, 12:00
I have and error when using setScale method: none of the 4 overloads could convert all the argument types.



QList<double> ticks [QwtScaleDiv::NTickTypes];
for(int i=0; i<timeSamples.size(); i++)
ticks[0].append(timeSamples.at(i));//<<0.5<<1.5<<2.5<<3.5<<4.5<<5.5<<6.5<<7.5<<8.5<<9.5;
ui.timeSampleSlider->setScale(QwtScaleDiv(start, end), ticks);
ui.timeSampleSlider->setRange(start, end);
ui.timeSampleSlider->setScaleMaxMinor(0);
ui.timeSampleSlider->setValue(start);
ui.timeSampleSlider->setEnabled(true);

Uwe
7th September 2012, 12:13
Of course not - ticks is a parameter of the QwtScaleDiv constructor. Are you familiar with C++ ?

Uwe

RomanRdgz
7th September 2012, 13:07
Ok, it was a mistake while reading. SHould have copy-pasted your lines.

Anyway it doesn't work. It looks just as my second test (see second image at the first post). And it allows user to stop at any possible value into the range, which didn't before. I guess that's for not using the third parameter at setRange method.

Any other possible approach?

Uwe
7th September 2012, 13:34
Anyway it doesn't work.
When you assign the values from your timeSamples array as ticks, then you get these values as ticks. When you don't want them don't assign them.
Come on - this thread is about 3 simple lines of code - all you need to do is to copy what I have posted.

Uwe

RomanRdgz
7th September 2012, 13:46
I am assigning the values I want for my ticks. That's what I was trying to do myself even before posting this. I have copied your lines of code exactly and if my input ticks are 500, 1500, 2500... 9500, the only labels I'm getting are 2000, 4000, 6000 and 800, just as at the beginning.

My code is the one I shown two answers ago, when I had a mistake with the setScale, but now that method is jsut as you suggested. Doesn't work.



QList<double> ticks [QwtScaleDiv::NTickTypes];
for(int i=0; i<timeSamples.size(); i++)
ticks[0].append(timeSamples.at(i)); //Timesamples has inside: 500, 1500, 2500...9500
ui.timeSampleSlider->setScale(QwtScaleDiv(start, end, ticks)); // start is 500, end is 9500
ui.timeSampleSlider->setRange(start, end);
ui.timeSampleSlider->setScaleMaxMinor(0);
ui.timeSampleSlider->setValue(start);
ui.timeSampleSlider->setEnabled(true);

Uwe
7th September 2012, 14:21
Build and run the application below ( unmodified - please no more modifications from your code ).

Isn't this what you want ?


#include <qapplication.h>
#include <qwt_slider.h>
#include <qwt_scale_div.h>

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QwtSlider slider( NULL, Qt::Horizontal, QwtSlider::BottomScale );

QList< double > ticks[ QwtScaleDiv::NTickTypes ];
ticks[ QwtScaleDiv::MajorTick ] << 500 << 1500 << 2500 << 3500
<< 4500 << 5500 << 6500 << 7500 << 8500 << 9500;

slider.setScale( QwtScaleDiv( 500, 9500, ticks ) );
slider.setRange( 500, 9500, 1000 );

slider.show();

return a.exec();
}

This is really a "schwere Geburt",

Uwe

RomanRdgz
10th September 2012, 08:09
Ok, it does work now. The problematic line was:


ui.timeSampleSlider->setScaleMaxMinor(0);

Which is weird, but without that line my code works exactly as yours. Thanks for your time!

RomanRdgz
10th September 2012, 11:43
One more question: about the method you gave me before to customize the labels, how could I use it?

I am accessing the QwtSlider from the ui, with ui.timeSampleSlider, as you have already seen when I showed code here. I know I can get the ScaleDraw associated to my QwtSlider with the scaleDraw() method, but I don't know how to write the function you gave me then.

I can think of:


virtual QwtText ui.timeSampleSlider.scaleDraw()::label( double value ) const
{
return QwtScaleDraw::label( value / 1000.0 );
}


which is obviously wrong, but I can't think of how to access to the ScaleDraw. By the way, I'm writting this method into my code, into the same cpp file I have been working before to set the ticks where I wanted.

How can I use this method then? Thanks once more!


Then set the ticks to 500, 1000 and modify how the tick labels are represented:


virtual QwtText YourScaleDraw::label( double value ) const
{
return QwtScaleDraw::label( value / 1000.0 );
}

HTH,
Uwe

Uwe
10th September 2012, 13:02
class YourScaleDraw: public QwtScaleDraw
{
public:
virtual QwtText label( double value ) const
{
return QwtScaleDraw::label( value / 1000.0 );
}
};

ui.timeSampleSlider->setScaleDraw( new YourScaleDraw() );
Assigning the YourScaleDraw object has to be done before you set the ticks !

But please stay to Qwt related questions, when posting here. There are other forums dedicated to C++.

Uwe