pyqt5 QSlider实现数轴但无法在数轴下方显示坐标对应的数值
做了个用QSlider实现[-10,10]的数轴类,但是并不能实现数轴下方显示对应的整数。求修正与优化其中这一段负责显示数轴下方的整数的代码:
text = str(value)
font_metrics = painter.fontMetrics()
text_width = font_metrics.width(text)
painter.drawText(x - text_width // 2, slider_height - 30, text)
这一段代码真不知道如何改。。尝试减少了数轴显示的数字的数量也依旧不能显示。不知如何解决
附上全部代码:
import sys
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSlider, QApplication
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QFontMetrics
class NumberLineSlider(QSlider):
def __init__(self, min_value, max_value, *args, **kwargs):
super().__init__(Qt.Horizontal, *args, **kwargs)
self.min_value = min_value
self.max_value = max_value
self.setMinimum(min_value)
self.setMaximum(max_value)
self.setTickPosition(QSlider.TicksBelow)
self.setTickInterval(1)# 设置每个刻度的间隔为1
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# 获取当前slider的大小
slider_width = self.width()
slider_height = self.height()
# 绘制每个整数标记
for value in range(self.min_value, self.max_value + 1):
# 计算每个数值的位置
x = self.position_for_value(value, slider_width)
# 绘制刻度线
painter.drawLine(x, slider_height - 20, x, slider_height - 10)
# 绘制数值文本
text = str(value)
font_metrics = painter.fontMetrics()
text_width = font_metrics.width(text)
painter.drawText(x - text_width // 2, slider_height - 30, text)
def position_for_value(self, value, slider_width):
"""计算给定数值在滑块上的 x 坐标"""
slider_min = self.minimum()
slider_max = self.maximum()
# 计算数值相对slider宽度的位置
return int((value - slider_min) / (slider_max - slider_min) * (slider_width - 20)) + 10
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 设置数轴范围,从 -10 到 10
self.slider = NumberLineSlider(-10, 10)
self.label = QLabel("Move the slider to see the value")
# 当滑块移动时,更新标签显示的值
self.slider.valueChanged.connect(self.on_slider_value_changed)
# 布局
layout = QVBoxLayout()
layout.addWidget(self.slider)
layout.addWidget(self.label)
self.setLayout(layout)
def on_slider_value_changed(self, value):
# 更新标签显示当前滑块值
self.label.setText(f"Value: {value}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_()) 看你的代码,主要的问题在于计算 QSlider 的数值位置和进行drawText操作的地方。这里给你一个修正和优化的版本,希望能帮助你解决问题。
import sys
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSlider, QApplication
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QFontMetrics
class NumberLineSlider(QSlider):
def __init__(self, min_value, max_value, *args, **kwargs):
super().__init__(Qt.Horizontal, *args, **kwargs)
self.min_value = min_value
self.max_value = max_value
self.setMinimum(min_value)
self.setMaximum(max_value)
self.setTickPosition(QSlider.TicksBelow)
self.setTickInterval(1)# 设置每个刻度的间隔为1
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
slider_width = self.width()
slider_height = self.height()
for value in range(self.min_value, self.max_value + 1):
x = self.position_for_value(value, slider_width)
painter.drawLine(x, slider_height - 20, x, slider_height - 10)
text = str(value)
font_metrics = painter.fontMetrics()
text_width = font_metrics.horizontalAdvance(text)# 更新点:使用 horizontalAdvance 而不是 width
painter.drawText(x - text_width // 2, slider_height - 30, text)
def position_for_value(self, value, slider_width):
"""计算给定数值在滑块上的 x 坐标"""
slider_min = self.minimum()
slider_max = self.maximum()
if slider_max == slider_min:
return 0
return int(slider_width * (value - slider_min) / (slider_max - slider_min))
# 主窗口
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Number Line Slider Example')
self.setGeometry(100, 100, 600, 100)
layout = QVBoxLayout()
self.slider = NumberLineSlider(0, 10)
layout.addWidget(self.slider)
self.value_label = QLabel("0")
layout.addWidget(self.value_label)
self.slider.valueChanged.connect(self.update_label)
self.setLayout(layout)
def update_label(self, value):
self.value_label.setText(str(value))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
主要修改点:
1. 使用 `font_metrics.horizontalAdvance(text)` 而不是 `font_metrics.width(text)`。`horizontalAdvance` 是计算字符串显示长度的更现代化方法。
2. 增加了超出显示范围的处理。比如当 `self.minimum()` 和 `self.maximum()` 值相等时防止除以零错误。
3. 为方便测试,增加一个主窗口类 `MainWindow`, 承载 `NumberLineSlider` 并且显示当前的 Slider 值。
希望对你有帮助!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]