본문 바로가기

두 개의 바를 사용하여 최대값, 최소값 조정하는 슬라이더 PyQt5 예제

webnautes 2024. 8. 9.
반응형

두 개의 바를 사용하여 최대값, 최소값 조정하는 슬라이더 PyQt5  예제입니다.

 

2024. 8. 9 최초작성







from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QLabel
from PyQt5.QtCore import Qt, pyqtSignal, QRectF
from PyQt5.QtGui import QPainter, QColor, QPen

class RangeSlider(QWidget):
    valueChanged = pyqtSignal(int, int)

    def __init__(self, values, parent=None):
        super().__init__(parent)
        self.values = values
        self.first_position = 0
        self.second_position = len(values) - 1
        self.moving = None
        self.handle_radius = 10
        self.padding = self.handle_radius + 2  # 패딩 추가
        self.setMinimumHeight(2 * (self.handle_radius + self.padding))

    def mousePressEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            x = event.pos().x()
            distance_first = abs(self.positionToX(self.first_position) - x)
            distance_second = abs(self.positionToX(self.second_position) - x)
            if distance_first < distance_second:
                self.moving = "first"
            else:
                self.moving = "second"

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            x = event.pos().x()
            position = self.xToPosition(x)
            if self.moving == "first" and position < self.second_position:
                self.first_position = position
            elif self.moving == "second" and position > self.first_position:
                self.second_position = position
            self.update()
            self.valueChanged.emit(self.values[self.first_position], self.values[self.second_position])

    def mouseReleaseEvent(self, event):
        self.moving = None

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        # 그리기 영역 조정
        draw_area = self.width() - 2 * self.padding
        start_x = self.padding
        end_x = self.width() - self.padding

        # Draw the line
        pen = QPen(QColor(200, 200, 200))
        pen.setWidth(4)
        painter.setPen(pen)
        painter.drawLine(start_x, self.height() // 2, end_x, self.height() // 2)

        # Draw the handles
        painter.setBrush(QColor(255, 255, 255))
        painter.drawEllipse(QRectF(self.positionToX(self.first_position) - self.handle_radius,
                            self.height() // 2 - self.handle_radius,
                            self.handle_radius * 2, self.handle_radius * 2))
        painter.drawEllipse(QRectF(self.positionToX(self.second_position) - self.handle_radius,
                            self.height() // 2 - self.handle_radius,
                            self.handle_radius * 2, self.handle_radius * 2))

    def positionToX(self, position):
        draw_area = self.width() - 2 * self.padding
        return int(position * draw_area / (len(self.values) - 1)) + self.padding

    def xToPosition(self, x):
        draw_area = self.width() - 2 * self.padding
        adjusted_x = max(self.padding, min(x, self.width() - self.padding)) - self.padding
        return min(max(round(adjusted_x * (len(self.values) - 1) / draw_area), 0), len(self.values) - 1)

class PriceRangeWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.values = [20, 35, 50, 75, 100, 150, 200, 250# 사전 정의된 값 리스트
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout()
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(10)

        self.range_slider = RangeSlider(self.values)
        self.range_slider.valueChanged.connect(self.updateLabels)

        self.min_label = QLabel(f'최소: {self.values[0]}만원')
        self.max_label = QLabel(f'최대: {self.values[-1]}만원')

        font = self.min_label.font()
        font.setPointSize(12)
        self.min_label.setFont(font)
        self.max_label.setFont(font)

        layout.addWidget(self.min_label)
        layout.addWidget(self.range_slider)
        layout.addWidget(self.max_label)

        self.setLayout(layout)
        self.setWindowTitle('가격 범위 설정')
        self.setMinimumSize(400, 150)

    def updateLabels(self, min_val, max_val):
        self.min_label.setText(f'최소: {min_val}만원')
        self.max_label.setText(f'최대: {max_val}만원')

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    ex = PriceRangeWidget()
    ex.show()
    sys.exit(app.exec_())


반응형

'Qt > PyQt5 강좌' 카테고리의 다른 글

PyQt5 검색창 UI 예제  (0) 2024.08.12
pyQt5 QDoubleSpinBox 예제  (0) 2024.08.11
pyQt5 다중 탭에 텍스트 에디터가 포함된 예제  (0) 2024.08.08
PyQt5 콤보박스(QComboBox) 예제  (0) 2024.07.06
PyQt5 QTableWidget 예제  (0) 2024.05.23

시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.

블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.



영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com


제가 쓴 책도 한번 검토해보세요 ^^

댓글