Custom Slider Widget with Preview
Topic: Custom Widgets and Components
In this example, we'll create a custom "Slider With Preview" widget using PyQt6. This widget will have a slider that displays a preview of the current value, which can be especially useful for media players or other applications that require users to adjust a value within a specific range.
slider_with_preview.py
import sys
from PyQt6.QtCore import Qt, QObject, pyqtSlot
from PyQt6.QtGui import QPainter, QBrush, QColor
from PyQt6.QtWidgets import QApplication, QWidget, QSlider, QHBoxLayout
class SliderWithPreview(QSlider):
def __init__(self, parent=None):
super().__init__(parent)
self._preview_value = self.minimum()
self._preview_rect = None
def paintEvent(self, event):
super().paintEvent(event)
self._paint_preview(event)
def _paint_preview(self, event):
painter = QPainter(self)
painter.setRenderHint(painter.Antialiasing)
preview_x = self._preview_rect.x() if self._preview_rect else 0
preview_y = self._preview_rect.y() if self._preview_rect else 0
preview_w = self._preview_rect.width() if self._preview_rect else 0
preview_h = self._preview_rect.height() if self._preview_rect else 0
if preview_w == 0:
preview_w = 20
preview_h = 20
preview_x = self.width() - preview_w - 5
preview_y = 5
painter.setPen(QColor('black'))
painter.setBrush(QColor('lightblue'))
painter.drawRoundedRect(preview_x, preview_y, preview_w, preview_h, 5, 5)
painter.setPen(QColor('black'))
painter.drawText(preview_x + 5, preview_y + 15, f"{self._preview_value}")
def resizeEvent(self, event):
super().resizeEvent(event)
self._update_preview_rect()
def _update_preview_rect(self):
slider_height = self.height()
preview_w = 20
preview_h = 20
preview_x = self.width() - preview_w - 5
preview_y = (slider_height - preview_h) // 2
self._preview_rect = (preview_x, preview_y, preview_w, preview_h)
def _calculate_preview_value(self):
range_value = self.maximum() - self.minimum()
slider_value = self.value() - self.minimum()
preview_value = self.minimum() + int((slider_value / range_value) * range_value)
return preview_value
@pyqtSlot(int)
def on_slider_value_changed(self, value):
self._preview_value = self._calculate_preview_value()
self.update()
class CustomWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.slider = SliderWithPreview()
self.slider.setRange(0, 100)
layout = QHBoxLayout()
layout.addWidget(self.slider)
self.setLayout(layout)
self.slider.valueChanged.connect(self.slider.on_slider_value_changed)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = CustomWidget()
widget.show()
sys.exit(app.exec())
Explanation
We create a custom SliderWithPreview
widget by subclassing QSlider
. This custom widget will display a preview of the current value next to the slider.
_paint_preview method
This method is responsible for painting the preview. It creates a QPainter
object, sets its render hint to Antialiasing
for a smoother preview, and then draws a lightblue rounded rectangle with the current value.
resizeEvent and _update_preview_rect methods
When the slider's size is updated, we update the position and size of the preview rectangle.
on_slider_value_changed slot
When the slider's value changes, we calculate the new preview value and update the widget to display the new preview.
CustomWidget
We create a CustomWidget
that creates an instance of the SliderWithPreview
widget, adds a layout, and sets the connections between the slider's valueChanged
signal and the on_slider_value_changed
slot.
Output
When you run this code, you should see a custom slider widget with a preview of the current value.
Design Considerations
To enhance app design and development, you can further customize this widget by adding additional features, such as:
- Customizable fonts and colors.
- Rounded rectangle edges or other shapes for the preview.
- The ability to set a specific width or height for the preview.
- Additional preview layouts for horizontal or vertical sliders.
These design considerations will help create a more modern and user-friendly widget that enhances the overall app design and user experience.
Images

Comments