圆月山庄资源网 Design By www.vgjia.com
本文通过Python3+PyQt5实现自定义部件–分数滑块。它既能支持键盘也支持鼠标,使用物理(视口)坐标通过绘制方式显示。
#!/usr/bin/env python3 import platform from PyQt5.QtCore import (QPointF, QRectF, QSize, Qt,pyqtSignal) from PyQt5.QtWidgets import (QApplication, QDialog,QSizePolicy, QGridLayout, QLCDNumber, QLabel, QSpinBox, QWidget) from PyQt5.QtGui import QColor,QFont,QPainter,QFontMetricsF,QPalette, QPolygonF X11 = True try: from PyQt5.QtGui import qt_x11_wait_for_window_manager except ImportError: X11 = False class FractionSlider(QWidget): XMARGIN = 12.0 YMARGIN = 5.0 WSTRING = "999" valueChanged = pyqtSignal(int,int) def __init__(self, numerator=0, denominator=10, parent=None): super(FractionSlider, self).__init__(parent) self.__numerator = numerator self.__denominator = denominator self.setFocusPolicy(Qt.WheelFocus) self.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)) def decimal(self): return self.__numerator / float(self.__denominator) def fraction(self): return self.__numerator, self.__denominator def sizeHint(self): return self.minimumSizeHint() def minimumSizeHint(self): font = QFont(self.font()) font.setPointSize(font.pointSize() - 1) fm = QFontMetricsF(font) return QSize(fm.width(FractionSlider.WSTRING) * self.__denominator, (fm.height() * 4) + FractionSlider.YMARGIN) def setFraction(self, numerator, denominator=None): if denominator is not None: if 3 <= denominator <= 60: self.__denominator = denominator else: raise ValueError("denominator out of range") if 0 <= numerator <= self.__denominator: self.__numerator = numerator else: raise ValueError("numerator out of range") self.update() self.updateGeometry() def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.moveSlider(event.x()) event.accept() else: QWidget.mousePressEvent(self, event) def mouseMoveEvent(self, event): self.moveSlider(event.x()) def moveSlider(self, x): span = self.width() - (FractionSlider.XMARGIN * 2) offset = span - x + FractionSlider.XMARGIN numerator = int(round(self.__denominator * (1.0 - (offset / span)))) numerator = max(0, min(numerator, self.__denominator)) if numerator != self.__numerator: self.__numerator = numerator #self.emit(SIGNAL("valueChanged(int,int)"), # self.__numerator, self.__denominator) self.valueChanged.emit(self.__numerator, self.__denominator) self.update() def keyPressEvent(self, event): change = 0 if event.key() == Qt.Key_Home: change = -self.__denominator elif event.key() in (Qt.Key_Up, Qt.Key_Right): change = 1 elif event.key() == Qt.Key_PageUp: change = (self.__denominator // 10) + 1 elif event.key() in (Qt.Key_Down, Qt.Key_Left): change = -1 elif event.key() == Qt.Key_PageDown: change = -((self.__denominator // 10) + 1) elif event.key() == Qt.Key_End: change = self.__denominator if change: numerator = self.__numerator numerator += change numerator = max(0, min(numerator, self.__denominator)) if numerator != self.__numerator: self.__numerator = numerator #self.emit(SIGNAL("valueChanged(int,int)"), # self.__numerator, self.__denominator) self.valueChanged.emit(self.__numerator, self.__denominator) self.update() event.accept() else: QWidget.keyPressEvent(self, event) def paintEvent(self, event=None): font = QFont(self.font()) font.setPointSize(font.pointSize() - 1) fm = QFontMetricsF(font) fracWidth = fm.width(FractionSlider.WSTRING) indent = fm.boundingRect("9").width() / 2.0 if not X11: fracWidth *= 1.5 span = self.width() - (FractionSlider.XMARGIN * 2) value = self.__numerator / float(self.__denominator) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) painter.setPen(self.palette().color(QPalette.Mid)) painter.setBrush(self.palette().brush( QPalette.AlternateBase)) painter.drawRect(self.rect()) segColor = QColor(Qt.green).darker(120) segLineColor = segColor.darker() painter.setPen(segLineColor) painter.setBrush(segColor) painter.drawRect(FractionSlider.XMARGIN, FractionSlider.YMARGIN, span, fm.height()) textColor = self.palette().color(QPalette.Text) segWidth = span / self.__denominator segHeight = fm.height() * 2 nRect = fm.boundingRect(FractionSlider.WSTRING) x = FractionSlider.XMARGIN yOffset = segHeight + fm.height() for i in range(self.__denominator + 1): painter.setPen(segLineColor) painter.drawLine(x, FractionSlider.YMARGIN, x, segHeight) painter.setPen(textColor) y = segHeight rect = QRectF(nRect) rect.moveCenter(QPointF(x, y + fm.height() / 2.0)) #painter.drawText(rect, Qt.AlignCenter, #QString.number(i)) painter.drawText(rect, Qt.AlignCenter,str(i)) y = yOffset rect.moveCenter(QPointF(x, y + fm.height() / 2.0)) painter.drawText(rect, Qt.AlignCenter, str(self.__denominator)) painter.drawLine(QPointF(rect.left() + indent, y), QPointF(rect.right() - indent, y)) x += segWidth span = int(span) y = FractionSlider.YMARGIN - 0.5 triangle = [QPointF(value * span, y), QPointF((value * span) + (2 * FractionSlider.XMARGIN), y), QPointF((value * span) + FractionSlider.XMARGIN, fm.height())] painter.setPen(Qt.yellow) painter.setBrush(Qt.darkYellow) painter.drawPolygon(QPolygonF(triangle)) if __name__ == "__main__": import sys app = QApplication(sys.argv) form = QDialog() sliderLabel = QLabel("&Fraction") slider = FractionSlider(denominator=12) sliderLabel.setBuddy(slider) denominatorLabel = QLabel("&Denominator") denominatorSpinBox = QSpinBox() denominatorLabel.setBuddy(denominatorSpinBox) denominatorSpinBox.setRange(3, 60) denominatorSpinBox.setValue(slider.fraction()[1]) denominatorSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter) numeratorLabel = QLabel("Numerator") numeratorLCD = QLCDNumber() numeratorLCD.setSegmentStyle(QLCDNumber.Flat) layout = QGridLayout() layout.addWidget(sliderLabel, 0, 0) layout.addWidget(slider, 0, 1, 1, 5) layout.addWidget(numeratorLabel, 1, 0) layout.addWidget(numeratorLCD, 1, 1) layout.addWidget(denominatorLabel, 1, 2) layout.addWidget(denominatorSpinBox, 1, 3) form.setLayout(layout) def valueChanged(denominator): numerator = int(slider.decimal() * denominator) slider.setFraction(numerator, denominator) numeratorLCD.display(numerator) #form.connect(slider, SIGNAL("valueChanged(int,int)"), #numeratorLCD, SLOT("display(int)")) slider.valueChanged[int,int].connect(numeratorLCD.display) #form.connect(denominatorSpinBox, SIGNAL("valueChanged(int)"), #valueChanged) denominatorSpinBox.valueChanged[int].connect(valueChanged) form.setWindowTitle("Fraction Slider") form.show() app.exec_()
运行结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
圆月山庄资源网 Design By www.vgjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
圆月山庄资源网 Design By www.vgjia.com
暂无评论...
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
2024年11月07日
2024年11月07日
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]