PDA

View Full Version : PySide2 QSlider expanding drawable area and tick label customization



Vesnog
29th January 2019, 21:55
I am a new Qt user and designing a controller interface. By overloading the paintEvent of the QSlider I was able to draw ticks labels and tick marks. However, the first and last of these tick labels were clipped from the top and bottom, respectively. Please see the attached screenshot for an illustration.

13015

So far I have tried setting the contents margins with setContentsMargins and changing the style which did not work at all. Here is an example code which reproduces the situation I was talking about. Is it possible to expand the drawable area around the QSlider so that the labels will not be cropped? If so how can it be done in Python?

Thanks in advance


import sys
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *

slider_x = 150
slider_y = 450
slider_step = [0.01, 0.1, 1, 10, 100] # in microns


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

def paintEvent(self, event):
super(MySlider, self).paintEvent(event)
qp = QPainter(self)
pen = QPen()
pen.setWidth(2)
pen.setColor(Qt.red)

qp.setPen(pen)
font = QFont('Times', 10)
qp.setFont(font)
self.setContentsMargins(50, 50, 50, 50)
# size = self.size()
# print(size)
# print("margins", self.getContentsMargins())
# print(self.getContentsMargins())
# print(self.contentsRect())
contents = self.contentsRect()
print(contents.x())
self.setFixedSize(QSize(slider_x, slider_y))
max_slider = self.maximum()
y_inc = 0
for i in range(max_slider):
qp.drawText(contents.x() - font.pointSize(), y_inc + font.pointSize() / 2, '{0:2}'.format(slider_step[i]))
qp.drawLine(contents.x() + font.pointSize(), y_inc, contents.x() + contents.width(), y_inc)
y_inc += slider_y/4


class Window(QWidget):
""" Inherits from QWidget """
def __init__(self):
super().__init__()
self.title = 'Control Stages'
self.left = 10
self.top = 10
self.width = 320
self.height = 100
self.AxesMapping = [0, 1, 2, 3]
self.initUI()

def initUI(self):
""" Initializes the GUI either using the grid layout or the absolute position layout"""
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
Comp4 = self.createSlider("step_size")
Comp5 = self.createSlider("speed")
windowLayout = QGridLayout()
windowLayout.setContentsMargins(50, 50, 50, 50)
HGroupBox = QGroupBox()
layout = QGridLayout()
layout.addWidget(Comp4, 0, 0)
layout.addWidget(Comp5, 0, 1)
HGroupBox.setLayout(layout)
HGroupBox.setFixedSize(QSize(740, 480))
windowLayout.addWidget(HGroupBox, 0, 0)
self.setLayout(windowLayout)
self.show()

def createSlider(self, variant):
Slider = MySlider(Qt.Vertical)
Slider.Type = variant
Slider.setMaximum(5)
Slider.setMinimum(1)
Slider.setSingleStep(1)
Slider.setTickInterval(1)
Slider.valueChanged.connect(lambda: self.sliderChanged(Slider))
return Slider

@staticmethod
def sliderChanged(Slider):
print("Slider value changed to ", Slider.value(), "slider type is ", Slider.Type)
if Slider.Type == "step_size":
print("this is a step size slider")
elif Slider.Type == "speed":
print("this is a speed slider")


if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec_())

anda_skoa
3rd February 2019, 08:52
If your custom drawing code needs more space than the Slider would normally allocate, you can try overriding sizeHint() and minimumSizeHint() to ask the layout for more space.

Alternatively using a custom style of proxy style and requesting a larger area in sizeFormContents()

Cheers,
_

Vesnog
6th February 2019, 23:15
If your custom drawing code needs more space than the Slider would normally allocate, you can try overriding sizeHint() and minimumSizeHint() to ask the layout for more space.

Alternatively using a custom style of proxy style and requesting a larger area in sizeFormContents()

Cheers,
_

Thanks for your answer, I solved it by using style sheets and defining custom groove lengths as can be seen in my post on stackoverflow (https://stackoverflow.com/questions/54244990/is-it-possible-to-expand-the-drawable-area-around-the-qslider). I will try your solution when I have the time.