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?

+3


source to share


2 answers


Your question is not that simple. Here's my not perfect solution:

  • First, we need to track QSlider

    , so you need to replace everything slider

    with self.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

    is QRect

    and has several methods: get the position in pixels.
    You can either int

    with QRect.bottom()

    , QRect.right()

    ... or QPoint

    with QRect.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

.

+3


source


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)

      

+4


source







All Articles