Qt/PyQt5 강좌
두 개의 바를 사용하여 최대값, 최소값 조정하는 슬라이더 PyQt5 예제
webnautes
2024. 8. 9. 22:50
반응형
두 개의 바를 사용하여 최대값, 최소값 조정하는 슬라이더 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_()) |
반응형