当前位置:Gxlcms > Python > python3+PyQt5实现自定义分数滑块部件

python3+PyQt5实现自定义分数滑块部件

时间:2021-07-01 10:21:17 帮助过:54人阅读

这篇文章主要为大家详细介绍了python3+PyQt5实现自定义分数滑块部件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文通过Python3+PyQt5实现自定义部件–分数滑块。它既能支持键盘也支持鼠标,使用物理(视口)坐标通过绘制方式显示。

  1. #!/usr/bin/env python3
  2. import platform
  3. from PyQt5.QtCore import (QPointF, QRectF, QSize, Qt,pyqtSignal)
  4. from PyQt5.QtWidgets import (QApplication, QDialog,QSizePolicy,
  5. QGridLayout, QLCDNumber, QLabel,
  6. QSpinBox, QWidget)
  7. from PyQt5.QtGui import QColor,QFont,QPainter,QFontMetricsF,QPalette, QPolygonF
  8. X11 = True
  9. try:
  10. from PyQt5.QtGui import qt_x11_wait_for_window_manager
  11. except ImportError:
  12. X11 = False
  13. class FractionSlider(QWidget):
  14. XMARGIN = 12.0
  15. YMARGIN = 5.0
  16. WSTRING = "999"
  17. valueChanged = pyqtSignal(int,int)
  18. def __init__(self, numerator=0, denominator=10, parent=None):
  19. super(FractionSlider, self).__init__(parent)
  20. self.__numerator = numerator
  21. self.__denominator = denominator
  22. self.setFocusPolicy(Qt.WheelFocus)
  23. self.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding,
  24. QSizePolicy.Fixed))
  25. def decimal(self):
  26. return self.__numerator / float(self.__denominator)
  27. def fraction(self):
  28. return self.__numerator, self.__denominator
  29. def sizeHint(self):
  30. return self.minimumSizeHint()
  31. def minimumSizeHint(self):
  32. font = QFont(self.font())
  33. font.setPointSize(font.pointSize() - 1)
  34. fm = QFontMetricsF(font)
  35. return QSize(fm.width(FractionSlider.WSTRING) *
  36. self.__denominator,
  37. (fm.height() * 4) + FractionSlider.YMARGIN)
  38. def setFraction(self, numerator, denominator=None):
  39. if denominator is not None:
  40. if 3 <= denominator <= 60:
  41. self.__denominator = denominator
  42. else:
  43. raise ValueError("denominator out of range")
  44. if 0 <= numerator <= self.__denominator:
  45. self.__numerator = numerator
  46. else:
  47. raise ValueError("numerator out of range")
  48. self.update()
  49. self.updateGeometry()
  50. def mousePressEvent(self, event):
  51. if event.button() == Qt.LeftButton:
  52. self.moveSlider(event.x())
  53. event.accept()
  54. else:
  55. QWidget.mousePressEvent(self, event)
  56. def mouseMoveEvent(self, event):
  57. self.moveSlider(event.x())
  58. def moveSlider(self, x):
  59. span = self.width() - (FractionSlider.XMARGIN * 2)
  60. offset = span - x + FractionSlider.XMARGIN
  61. numerator = int(round(self.__denominator *
  62. (1.0 - (offset / span))))
  63. numerator = max(0, min(numerator, self.__denominator))
  64. if numerator != self.__numerator:
  65. self.__numerator = numerator
  66. #self.emit(SIGNAL("valueChanged(int,int)"),
  67. # self.__numerator, self.__denominator)
  68. self.valueChanged.emit(self.__numerator, self.__denominator)
  69. self.update()
  70. def keyPressEvent(self, event):
  71. change = 0
  72. if event.key() == Qt.Key_Home:
  73. change = -self.__denominator
  74. elif event.key() in (Qt.Key_Up, Qt.Key_Right):
  75. change = 1
  76. elif event.key() == Qt.Key_PageUp:
  77. change = (self.__denominator // 10) + 1
  78. elif event.key() in (Qt.Key_Down, Qt.Key_Left):
  79. change = -1
  80. elif event.key() == Qt.Key_PageDown:
  81. change = -((self.__denominator // 10) + 1)
  82. elif event.key() == Qt.Key_End:
  83. change = self.__denominator
  84. if change:
  85. numerator = self.__numerator
  86. numerator += change
  87. numerator = max(0, min(numerator, self.__denominator))
  88. if numerator != self.__numerator:
  89. self.__numerator = numerator
  90. #self.emit(SIGNAL("valueChanged(int,int)"),
  91. # self.__numerator, self.__denominator)
  92. self.valueChanged.emit(self.__numerator, self.__denominator)
  93. self.update()
  94. event.accept()
  95. else:
  96. QWidget.keyPressEvent(self, event)
  97. def paintEvent(self, event=None):
  98. font = QFont(self.font())
  99. font.setPointSize(font.pointSize() - 1)
  100. fm = QFontMetricsF(font)
  101. fracWidth = fm.width(FractionSlider.WSTRING)
  102. indent = fm.boundingRect("9").width() / 2.0
  103. if not X11:
  104. fracWidth *= 1.5
  105. span = self.width() - (FractionSlider.XMARGIN * 2)
  106. value = self.__numerator / float(self.__denominator)
  107. painter = QPainter(self)
  108. painter.setRenderHint(QPainter.Antialiasing)
  109. painter.setRenderHint(QPainter.TextAntialiasing)
  110. painter.setPen(self.palette().color(QPalette.Mid))
  111. painter.setBrush(self.palette().brush(
  112. QPalette.AlternateBase))
  113. painter.drawRect(self.rect())
  114. segColor = QColor(Qt.green).darker(120)
  115. segLineColor = segColor.darker()
  116. painter.setPen(segLineColor)
  117. painter.setBrush(segColor)
  118. painter.drawRect(FractionSlider.XMARGIN,
  119. FractionSlider.YMARGIN, span, fm.height())
  120. textColor = self.palette().color(QPalette.Text)
  121. segWidth = span / self.__denominator
  122. segHeight = fm.height() * 2
  123. nRect = fm.boundingRect(FractionSlider.WSTRING)
  124. x = FractionSlider.XMARGIN
  125. yOffset = segHeight + fm.height()
  126. for i in range(self.__denominator + 1):
  127. painter.setPen(segLineColor)
  128. painter.drawLine(x, FractionSlider.YMARGIN, x, segHeight)
  129. painter.setPen(textColor)
  130. y = segHeight
  131. rect = QRectF(nRect)
  132. rect.moveCenter(QPointF(x, y + fm.height() / 2.0))
  133. #painter.drawText(rect, Qt.AlignCenter,
  134. #QString.number(i))
  135. painter.drawText(rect, Qt.AlignCenter,str(i))
  136. y = yOffset
  137. rect.moveCenter(QPointF(x, y + fm.height() / 2.0))
  138. painter.drawText(rect, Qt.AlignCenter,
  139. str(self.__denominator))
  140. painter.drawLine(QPointF(rect.left() + indent, y),
  141. QPointF(rect.right() - indent, y))
  142. x += segWidth
  143. span = int(span)
  144. y = FractionSlider.YMARGIN - 0.5
  145. triangle = [QPointF(value * span, y),
  146. QPointF((value * span) +
  147. (2 * FractionSlider.XMARGIN), y),
  148. QPointF((value * span) +
  149. FractionSlider.XMARGIN, fm.height())]
  150. painter.setPen(Qt.yellow)
  151. painter.setBrush(Qt.darkYellow)
  152. painter.drawPolygon(QPolygonF(triangle))
  153. if __name__ == "__main__":
  154. import sys
  155. app = QApplication(sys.argv)
  156. form = QDialog()
  157. sliderLabel = QLabel("&Fraction")
  158. slider = FractionSlider(denominator=12)
  159. sliderLabel.setBuddy(slider)
  160. denominatorLabel = QLabel("&Denominator")
  161. denominatorSpinBox = QSpinBox()
  162. denominatorLabel.setBuddy(denominatorSpinBox)
  163. denominatorSpinBox.setRange(3, 60)
  164. denominatorSpinBox.setValue(slider.fraction()[1])
  165. denominatorSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
  166. numeratorLabel = QLabel("Numerator")
  167. numeratorLCD = QLCDNumber()
  168. numeratorLCD.setSegmentStyle(QLCDNumber.Flat)
  169. layout = QGridLayout()
  170. layout.addWidget(sliderLabel, 0, 0)
  171. layout.addWidget(slider, 0, 1, 1, 5)
  172. layout.addWidget(numeratorLabel, 1, 0)
  173. layout.addWidget(numeratorLCD, 1, 1)
  174. layout.addWidget(denominatorLabel, 1, 2)
  175. layout.addWidget(denominatorSpinBox, 1, 3)
  176. form.setLayout(layout)
  177. def valueChanged(denominator):
  178. numerator = int(slider.decimal() * denominator)
  179. slider.setFraction(numerator, denominator)
  180. numeratorLCD.display(numerator)
  181. #form.connect(slider, SIGNAL("valueChanged(int,int)"),
  182. #numeratorLCD, SLOT("display(int)"))
  183. slider.valueChanged[int,int].connect(numeratorLCD.display)
  184. #form.connect(denominatorSpinBox, SIGNAL("valueChanged(int)"),
  185. #valueChanged)
  186. denominatorSpinBox.valueChanged[int].connect(valueChanged)
  187. form.setWindowTitle("Fraction Slider")
  188. form.show()
  189. app.exec_()

运行结果:


相关推荐:

python3+PyQt5实现自定义流体混合窗口部件

python3+PyQt5使用数据库表视图

python3+PyQt5实现拖放功能

以上就是python3+PyQt5实现自定义分数滑块部件的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行