PDA

View Full Version : Slider with log ticks?



drmacro
21st February 2017, 13:08
I've done a lot of searching on the web and in this forum, so I'm guessing I have not used the right search terms (or I'm the first to want to do this...which would be a first for me to have an original idea :p ).

I'm writing an audio oriented app in PyQt the normal scales for audio are log based.

So, what I want to do is display a slider that has ticks in a log spacing along the slider (i.e. not linear, in this particular case it would be decibels).

I have sliders and I already map the range of the slider to decibels for numerical display of the value, but have only figured out how to get ticks to be linear along the slider.

Since I haven't found any examples or even (at least to me) hints as how to attempt this, any pointers to docs or ideas are much appreciated.

Thanks,
Mac

Santosh Reddy
21st February 2017, 14:55
Assuming you are using QSlider based widget, it should be possible by overriding sliderChange() funciton

void QAbstractSlider::sliderChange(SliderChange change)[virtual protected]

drmacro
21st February 2017, 15:42
I am using QSlider.
The doc for sliderChange say: "Reimplement this virtual function to track slider changes such as SliderRangeChange..."

I don't see how this allows me to change the spacing of the ticks from linear to logarithmic. (It could my lack of understanding in general...but, I'm trying to learn.)

Santosh Reddy
22nd February 2017, 01:44
It may not be trivial but you can monitor the change in the slider value and adjust it to match the log scale you want.

Uwe
22nd February 2017, 09:44
Qwt http://qwt.sf.net offers sliders with logarithmic scales - see the controls example. Python wrappers for a current version of Qwt6 can be found here https://github.com/GauiStori/PyQt-Qwt, for Qwt5 there is pyqwt.

Uwe

drmacro
31st March 2017, 15:39
Thanks for the links to those scales and controls. I have a couple places in my code that those will come in handy. :)

And thanks to others for other suggestions.

As for my original question, I solved it with simple sub class of the slider paint:


class MySlider(QtWidgets.QSlider):
def __init__(self, parent=None):
super(MySlider, self).__init__(parent)

def paintEvent(self, event):
"""Paint log scale ticks"""
super(MySlider, self).paintEvent(event)
qp = QPainter(self)
pen = QPen()
pen.setWidth(2)
pen.setColor(Qt.black)

qp.setPen(pen)
font = QFont('Times', 10)
font_y_offset = font.pointSize()/2
qp.setFont(font)
size = self.size()
contents = self.contentsRect()
db_val_list = [10, 5, 0, -5, -10, -20, -30, -40, -50, -60, -90]
for val in db_val_list:
if val == 10:
y_val_fudge = 12
elif val == -90:
y_val_fudge = -12
db_scaled = db_to_int(val)
y_val = contents.height() - translate(db_scaled, 0, 1023, 0, contents.height())
if val == -90:
qp.drawText(contents.x() - font.pointSize(), y_val + font_y_offset + y_val_fudge, '-oo')
else:
qp.drawText(contents.x() - font.pointSize(), y_val + font_y_offset + y_val_fudge,'{0:2}'.format(val))
qp.drawLine(contents.x() + font.pointSize(), y_val + y_val_fudge, contents.x() + contents.width(), y_val + y_val_fudge)


It works, but after implementing it the GUI looked pretty bad with 30 sliders, side by side, with scales. Very cluttered.

d_stranz
1st April 2017, 16:44
It works, but after implementing it the GUI looked pretty bad with 30 sliders, side by side, with scales. Very cluttered.

Yeah, but that's sort of like what a sound board looks like, right? Maybe you can vary the appearance by grouping sets of related sliders and giving them a common color for their slider handles, or putting them in group boxes with different background colors. It doesn't have to be garish.

Or if all of the sliders don't have to be displayed at the same time, dividing them into groups on tabs, each tab controlling a specific set of functions.

Or if all the scales are the same, turning off tick labels and/or ticks for all except the ones on the ends of the rows.

drmacro
2nd April 2017, 16:49
Agreed, sound boards typically an intimidating array of knobs, buttons, indicators, and sliders.

All of your ideas are possibilities. Once I get the core of the application fleshed out I'll probably take another look at the ticks and labels.

As for the tab idea...I already have tabs for each mixer, so I'd have to have a tab widget in each mixers tab. Not sure how much layering becomes annoying and/or confusing.

But that's the sort of things that need to be worked out with GUI design. :p