How do I make a hint to follow the slider handler with PyQT?
Simple question: I am looking for an effect in pyqt like this:
JQuery UI slider, how to make window follow handler?
But this code is JQuery and I am trying to achieve it using PyQT
import sys
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 500)
self.setWindowTitle("PyQT example!")
slider = QtGui.QSlider(self)
slider.setOrientation(QtCore.Qt.Horizontal)
slider.move(50, 50)
slider.valueChanged.connect(self.value_changed)
self.show()
def value_changed(self, value):
QtGui.QToolTip.showText(QtGui.QCursor.pos(), str(value), self)
app = QtGui.QApplication(sys.argv)
GUI = Window()
sys.exit(app.exec_())
This code has successfully made a balloon over the cursor. Can I make a prompt to follow my slider handler now?
source to share
Your question is not that simple. Here's my not perfect solution:
-
First, we need to track
QSlider
, so you need to replace everythingslider
withself.slider
. -
From
QSlider
we can extract the rectangle containing the descriptor:style=self.slider.style() opt=QtGui.QStyleOptionSlider() self.slider.initStyleOption(opt) rectHandle=style.subControlRect(QtGui.QStyle.CC_Slider,opt, QtGui.QStyle.SC_SliderHandle,self)
-
rectHandle
isQRect
and has several methods: get the position in pixels.
You can eitherint
withQRect.bottom()
,QRect.right()
... orQPoint
withQRect.center()
,QRect.bottomRight
... All positions will refer to the parent widget, here is the slider. <w> As an example, to get the absolute position of the bottom-right corner of a rectangle, you can do:myPoint=rectHandle.bottomRight()+self.slider.pos()
-
To improve: find the right position for the tool tip Imagine your best attempt, with some magic numbers:
magicX = 5 magicY = 15 x = rectHandle.right() + rectHandle.width() + self.slider.pos().x() + magicX y = rectHandle.bottom() + rectHandle.height() + self.slider.pos().y() + magicY
-
Of course, we need to show the tooltip at our custom position:
QtGui.QToolTip.showText(QtCore.QPoint(x,y), str(value), self)
NB: All calculations are done using the method value_changed
.
source to share
I like @ tmoreau's idea, but it's better to add new logic to the QSlider subclass:
class TipSlider(QtGui.QSlider):
def __init__(self, *args, tip_offset=QPoint(0, -45)):
super(QtGui.QSlider, self).__init__(*args)
self.tip_offset = tip_offset
self.style = QtGui.QApplication.style()
self.opt = QtGui.QStyleOptionSlider()
self.valueChanged.connect(self.show_tip)
# self.enterEvent = self.show_tip
# self.mouseReleaseEvent = self.show_tip
def show_tip(self, _):
self.initStyleOption(self.opt)
rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt, self.style.SC_SliderHandle)
pos_local = rectHandle.topLeft() + self.tip_offset
pos_global = self.mapToGlobal(pos_local)
QtGui.QToolTip.showText(pos_global, str(self.value()), self)
source to share