Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.50 KB | None | 0 0
  1. from PyQt5.QtGui import QPainter, QPen, QFont
  2. from PyQt5.QtWidgets import QAbstractButton, QSlider, QWidget, QVBoxLayout, QHBoxLayout,\
  3. QStyleOptionSlider, QStyle
  4. from PyQt5.QtCore import Qt, QRect, QPoint
  5. import numpy as np
  6.  
  7. class LabeledSlider(QWidget):
  8. def __init__(self, minimum, maximum, interval=1, orientation=Qt.Horizontal,
  9. labels=None, p0=0, parent=None):
  10. super(LabeledSlider, self).__init__(parent=parent)
  11.  
  12. levels=range(minimum, maximum + interval, interval)
  13.  
  14. if labels is not None:
  15. if not isinstance(labels, (tuple, list)):
  16. raise Exception("<labels> is a list or tuple.")
  17. if len(labels) != len(levels):
  18. raise Exception("Size of <labels> doesn't match levels.")
  19. self.levels=list(zip(levels,labels))
  20. else:
  21. self.levels=list(zip(levels,map(str,levels)))
  22.  
  23. if orientation==Qt.Horizontal:
  24. self.layout=QVBoxLayout(self)
  25. elif orientation==Qt.Vertical:
  26. self.layout=QHBoxLayout(self)
  27. else:
  28. raise Exception("<orientation> wrong.")
  29.  
  30. # gives some space to print labels
  31. self.left_margin=10
  32. self.top_margin=10
  33. self.right_margin=10
  34. self.bottom_margin=10
  35.  
  36. self.layout.setContentsMargins(self.left_margin,self.top_margin,
  37. self.right_margin,self.bottom_margin)
  38.  
  39. self.sl=QSlider(orientation, self)
  40. self.sl.setMinimum(minimum)
  41. self.sl.setMaximum(maximum)
  42. self.sl.setValue(minimum)
  43. self.sl.setSliderPosition(p0)
  44. if orientation==Qt.Horizontal:
  45. self.sl.setTickPosition(QSlider.TicksBelow)
  46. self.sl.setMinimumWidth(300) # just to make it easier to read
  47. else:
  48. self.sl.setTickPosition(QSlider.TicksLeft)
  49. self.sl.setMinimumHeight(300) # just to make it easier to read
  50. self.sl.setTickInterval(interval)
  51. self.sl.setSingleStep(1)
  52.  
  53. self.layout.addWidget(self.sl)
  54.  
  55. def paintEvent(self, e):
  56.  
  57. super(LabeledSlider,self).paintEvent(e)
  58. style=self.sl.style()
  59. painter=QPainter(self)
  60. st_slider=QStyleOptionSlider()
  61. st_slider.initFrom(self.sl)
  62. st_slider.orientation=self.sl.orientation()
  63.  
  64. length=style.pixelMetric(QStyle.PM_SliderLength, st_slider, self.sl)
  65. available=style.pixelMetric(QStyle.PM_SliderSpaceAvailable, st_slider, self.sl)
  66.  
  67. for v, v_str in self.levels:
  68.  
  69. # get the size of the label
  70. rect=painter.drawText(QRect(), Qt.TextDontPrint, v_str)
  71.  
  72. if self.sl.orientation()==Qt.Horizontal:
  73. # I assume the offset is half the length of slider, therefore
  74. # + length//2
  75. x_loc=QStyle.sliderPositionFromValue(self.sl.minimum(),
  76. self.sl.maximum(), v, available)+length//2
  77.  
  78. # left bound of the text = center - half of text width + L_margin
  79. left=x_loc-rect.width()//2+self.left_margin
  80. bottom=self.rect().bottom()
  81.  
  82. # enlarge margins if clipping
  83. if v==self.sl.minimum():
  84. if left<=0:
  85. self.left_margin=rect.width()//2-x_loc
  86. if self.bottom_margin<=rect.height():
  87. self.bottom_margin=rect.height()
  88.  
  89. self.layout.setContentsMargins(self.left_margin,
  90. self.top_margin, self.right_margin,
  91. self.bottom_margin)
  92.  
  93. if v==self.sl.maximum() and rect.width()//2>=self.right_margin:
  94. self.right_margin=rect.width()//2
  95. self.layout.setContentsMargins(self.left_margin,
  96. self.top_margin, self.right_margin,
  97. self.bottom_margin)
  98.  
  99. else:
  100. y_loc=QStyle.sliderPositionFromValue(self.sl.minimum(),
  101. self.sl.maximum(), v, available, upsideDown=True)
  102.  
  103. bottom=y_loc+length//2+rect.height()//2+self.top_margin-3
  104. # there is a 3 px offset that I can't attribute to any metric
  105.  
  106. left=self.left_margin-rect.width()
  107. if left<=0:
  108. self.left_margin=rect.width()+2
  109. self.layout.setContentsMargins(self.left_margin,
  110. self.top_margin, self.right_margin,
  111. self.bottom_margin)
  112.  
  113. pos=QPoint(left, bottom)
  114. painter.drawText(pos, v_str)
  115.  
  116. return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement