I'm so stupid...
I have read the API, I have modified and given the correct variable but I
forgot to change the name of the function ... Lose as much time besause i'm
stupid ... It is by reading your post justin that I realized it. Because
actually the name of the function does not match what I call for my return
value. So it works very well ... I have a small problem but that is linked
to what I read on the internet to QT / PySide with the draw text. I have a
Direct crash during the drawText. I know how to get around it with labels
but it's not very clean. If I find a solution I will post it here. That's
where I am at the moment. I picked up two things on the internet to make a
slider with text and also a range slider.
#
================================================================================
# Import Modules
#
================================================================================
import os
import sys
from PySide import QtGui, QtCore
# ==========================================================
# TreeView
# ==========================================================
class RDSlider(QtGui.QSlider):
# ======================================================
# Init
# ======================================================
def __init__(self, qt_orientation=QtCore.Qt.Horizontal, qt_parent=None,
**kwargs):
super(RDSlider, self).__init__(qt_orientation, qt_parent)
# Init UI
self.setMinimum(kwargs.get("min", 0))
self.setMaximum(kwargs.get("max", 10))
self.setSingleStep(1)
self.setPageStep(1)
if kwargs.get("ticks", True) is True:
self.setTickPosition(kwargs.get("ticks_position",
QtGui.QSlider.TicksBelow))
self.__b_range_slider = kwargs.get("range_slider", False)
self.__b_ticks_text = kwargs.get("ticks_text", False)
# Range slider
self.__low = self.minimum()
self.__high = self.maximum()
self.__pressed_control = QtGui.QStyle.SC_None
self.__hover_control = QtGui.QStyle.SC_None
self.__click_offset = 0
self.__active_slider = 0
# ======================================================
# QT EVENT
# ======================================================
def paintEvent(self, event):
event.accept()
qt_painter = QtGui.QPainter(self)
style = QtGui.QApplication.style()
# ==================================================
# For range slider
if self.__b_range_slider is True:
for i, value in enumerate([self.__low, self.__high]):
qt_options = QtGui.QStyleOptionSlider()
self.initStyleOption(qt_options)
qt_options.subControls = QtGui.QStyle.SC_SliderHandle
if self.tickPosition() != self.NoTicks:
qt_options.subControls |=
QtGui.QStyle.SC_SliderTickmarks
if self.__pressed_control:
qt_options.activeSubControls = self.__pressed_control
qt_options.state |= QtGui.QStyle.State_Sunken
else:
qt_options.activeSubControls = self.__hover_control
qt_options.sliderPosition = value
qt_options.sliderValue = value
style.drawComplexControl(QtGui.QStyle.CC_Slider,
qt_options, qt_painter, self)
else:
super(RDSlider, self).paintEvent(event)
# ==================================================
# For text
if self.__b_ticks_text is True:
i_range = (self.maximum() - self.minimum()) + 1
for i in xrange(i_range):
# Get text and offset
s_text = "toto %s" % i
i_text_offset = -self.__get_text_offset(s_text)
if i == 0:
i_text_offset = 0.0
elif i != i_range - 1:
i_text_offset /= 2.0
# Draw text
if self.orientation() == QtCore.Qt.Horizontal:
qt_pos = QtCore.QPoint(self.__get_pos_from_value(i) +
i_text_offset, self.rect().bottom())
else:
qt_pos = QtCore.QPoint(self.rect().left(),
self.__get_pos_from_value(i) + i_text_offset)
qt_painter.drawText(qt_pos, s_text)
def mousePressEvent(self, event):
if self.__b_range_slider is True:
event.accept()
style = QtGui.QApplication.style()
button = event.button()
# In a normal slider control, when the user clicks on a point
in the
# slider's total range, but not on the slider part of the
control the
# control would jump the slider value to where the user clicked.
# For this control, clicks which are not direct hits will slide
both
# slider parts
if button:
qt_options = QtGui.QStyleOptionSlider()
self.initStyleOption(qt_options)
self.__active_slider = -1
for i, value in enumerate([self.__low, self.__high]):
qt_options.sliderPosition = value
hit = style.hitTestComplexControl(style.CC_Slider,
qt_options, event.pos(), self)
if hit == style.SC_SliderHandle:
self.__active_slider = i
self.__pressed_control = hit
self.triggerAction(self.SliderMove)
self.setRepeatAction(self.SliderNoAction)
self.setSliderDown(True)
break
if self.__active_slider < 0:
self.__pressed_control = QtGui.QStyle.SC_SliderHandle
self.__click_offset =
self.__get_value_from_pos(self.__pick(event.pos()))
self.triggerAction(self.SliderMove)
self.setRepeatAction(self.SliderNoAction)
else:
event.ignore()
else:
super(RDSlider, self).mousePressEvent(event)
event.ignore()
def mouseMoveEvent(self, event):
if self.__b_range_slider is True:
if self.__pressed_control != QtGui.QStyle.SC_SliderHandle:
event.ignore()
return
event.accept()
new_pos = self.__get_value_from_pos(self.__pick(event.pos()))
qt_options = QtGui.QStyleOptionSlider()
self.initStyleOption(qt_options)
if self.__active_slider < 0:
offset = new_pos - self.__click_offset
self.__high += offset
self.__low += offset
if self.__low < self.minimum():
diff = self.minimum() - self.__low
self.__low += diff
self.__high += diff
if self.__high > self.maximum():
diff = self.maximum() - self.__high
self.__low += diff
self.__high += diff
elif self.__active_slider == 0:
if new_pos >= self.__high:
new_pos = self.__high - 1
self.__low = new_pos
else:
if new_pos <= self.__low:
new_pos = self.__low + 1
self.__high = new_pos
self.__click_offset = new_pos
self.update()
self.emit(QtCore.SIGNAL('sliderMoved(int)'), new_pos)
else:
super(RDSlider, self).mouseMoveEvent(event)
event.ignore()
# ======================================================
# MISC
# ======================================================
def __pick(self, qt_point):
"""
!@Brief Mouse position from slider orientation
@type qt_point: QtGui.QPoint
@param qt_point: Mouse position
@rtype: float
@return: Value X or Y from slider orientation.
"""
if self.orientation() == QtCore.Qt.Horizontal:
return qt_point.x()
else:
return qt_point.y()
def __get_pos_from_value(self, i_value):
"""
!@Brief Get Pixel position of slider ticks.
@type i_value: int
@param i_value: Tick value.
@rtype: int
@return: Tick pixel position.
"""
qt_options = QtGui.QStyleOptionSlider()
self.initStyleOption(qt_options)
qt_style = QtGui.QApplication.style()
slider_groove = qt_style.subControlRect(qt_style.CC_Slider,
qt_options, qt_style.SC_SliderGroove, self)
slider_handle = qt_style.subControlRect(qt_style.CC_Slider,
qt_options, qt_style.SC_SliderHandle, self)
if self.orientation() == QtCore.Qt.Horizontal:
slider_length = slider_handle.width()
slider_min = slider_groove.x()
slider_max = slider_groove.right() - slider_length + 1
else:
slider_length = slider_handle.height()
slider_min = slider_groove.y()
slider_max = slider_groove.bottom() - slider_length + 1
return qt_style.sliderPositionFromValue(
self.minimum(),
self.maximum(),
i_value,
slider_max - slider_min,
qt_options.upsideDown
)
def __get_value_from_pos(self, f_pos):
"""
!@Brief Get Tick value from position.
@type f_pos: float
@param f_pos: Mouse position.
@rtype: int
@return: Tick value.
"""
qt_options = QtGui.QStyleOptionSlider()
self.initStyleOption(qt_options)
style = QtGui.QApplication.style()
slider_groove = style.subControlRect(style.CC_Slider, qt_options,
style.SC_SliderGroove, self)
slider_handle = style.subControlRect(style.CC_Slider, qt_options,
style.SC_SliderHandle, self)
if self.orientation() == QtCore.Qt.Horizontal:
slider_length = slider_handle.width()
slider_min = slider_groove.x()
slider_max = slider_groove.right() - slider_length + 1
else:
slider_length = slider_handle.height()
slider_min = slider_groove.y()
slider_max = slider_groove.bottom() - slider_length + 1
return style.sliderValueFromPosition(
self.minimum(),
self.maximum(),
f_pos - slider_min,
slider_max - slider_min,
qt_options.upsideDown
)
def __get_text_offset(self, s_text):
"""
!@Brief Get text length offset.
@type s_text: string
@param s_text: Text for get size.
@rtype: int
@return: Offset length.
"""
# Size from orientation
if self.orientation() == QtCore.Qt.Horizontal:
f_size = self.rect().width()
else:
f_size = self.rect().height()
qt_painter = QtGui.QPainter(self)
qt_font_metric = qt_painter.fontMetrics()
f_text_size = float(qt_font_metric.width(s_text))
i_percent_offset = (f_text_size / f_size) * 100.0
f_offset = f_size / 100.0 * i_percent_offset
return f_offset
# =============================================================
# INIT Script
# =============================================================
def main():
"""
!@Brief Main function for launch ui.
"""
app = QtGui.QApplication(sys.argv)
slider = RDSlider(min=0, max=6, range_slider=True)
slider.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/89e47c45-5d24-4292-b967-0428b5d14765%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.