A simple question, I am looking for a effect in pyqt like this:
Jquery UI slider how to make a box follow the handler?
But those code is JQuery and I am trying to achieve it with 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 successfully made tip balloon follow the cursor. Now is it possible to make the tip follow my slider handler?
I like @tmoreau's idea, but it is better to put new logic into a subclass of QSlider:
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)
Your question is not that simple. Here's my not perfect solution:
First, we need to keep track of the QSlider
, so you need to replace all slider
by self.slider
.
From the QSlider
, we can extract the rectangle that contains the handle:
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
is a QRect
, and has several method the get a position in pixels.
You can either can an int
with QRect.bottom()
, QRect.right()
... or a QPoint
with QRect.center()
, QRect.bottomRight
... All position will be relative to the parent widget, here the slider.
As an example, to get the absolute position of the rectangle's bottom right corner, you can do:
myPoint=rectHandle.bottomRight()+self.slider.pos()
To improve: finding the right position for the tool tip
Bellow my 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 the computing is done in value_changed
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With