2015-07-27 9 views
3

Простой вопрос, я ищу эффект в PyQt так:Как сделать подсказку, чтобы следить за обработчиком слайдера с помощью PyQT?

Jquery UI slider how to make a box follow the handler?

Но те, код JQuery, и я пытаюсь добиться этого с 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_()) 

Этот код успешно сделанный воздушным шаром подсказки, следуйте за курсором. Теперь можно сделать подсказку следовать за моим ползунком?

ответ

3

Ваш вопрос не такой простой. Вот мое не идеальное решение:

  1. Во-первых, мы должны следить за QSlider, так что вам нужно, чтобы заменить все slider на self.slider.

  2. Из QSlider, мы можем извлечь прямоугольник, содержащий ручку:

    style=self.slider.style() 
    opt=QtGui.QStyleOptionSlider() 
    self.slider.initStyleOption(opt) 
    rectHandle=style.subControlRect(QtGui.QStyle.CC_Slider,opt, QtGui.QStyle.SC_SliderHandle,self) 
    
  3. rectHandle является QRect, и имеет несколько метод ГЭТ позицию в пикселях.
    Вы можете либо может ли int с QRect.bottom(), QRect.right() ... или QPoint с QRect.center(), QRect.bottomRight ... Все позиции будет относительно родительского виджета, здесь слайдера.
    В качестве примера, чтобы получить абсолютное положение нижнего правого угла прямоугольника, вы можете сделать:

    myPoint=rectHandle.bottomRight()+self.slider.pos() 
    
  4. Для улучшения: найти правильное положение для кончика инструмента
    пыльник моей лучшей попытки, с некоторыми магическими числами:

    magicX = 5 
    magicY = 15 
    
    x = rectHandle.right() + rectHandle.width() + self.slider.pos().x() + magicX 
    y = rectHandle.bottom() + rectHandle.height() + self.slider.pos().y() + magicY 
    
  5. конечно, мы должны показать всплывающую подсказку в нашей пользовательской позиции:

    QtGui.QToolTip.showText(QtCore.QPoint(x,y), str(value), self) 
    

NB: Все вычисления сделано в value_changed методом.

+0

Очень четкий ответ! – BangZ

4

Мне нравится @ идея tmoreau, но это лучше поставить новую логику в подкласс 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)