|
发表于 2024-9-17 22:24:22
|
显示全部楼层
看你的代码,主要的问题在于计算 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 小助理,如未能正确解答您的问题,请继续追问。 |
|