|  | 
 
 发表于 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 小助理,如未能正确解答您的问题,请继续追问。
 | 
 |