Napisano 5 Październik 20177 l Jakiś czas temu szukałem widgeta od "buforowania" (ten kręcący się wiatraczek), nie znalazłem i użyłem gifa. Mam trochę czasu w domu to napisałem taki widgecik. Może komuś się przyda :) from PySide.QtGui import QWidget from PySide.QtGui import QPainter from PySide.QtGui import QColor from PySide.QtCore import QTimer, Qt, QRect from PySide.QtCore import Slot import time class SpinningWheelWidget(QWidget): def __init__(self, parent=None, spin_steps=12, bar_roundness=1.0, ticker_color=QColor(255, 255, 255), fade_to_color=QColor(32, 32, 32)): QWidget.__init__(self, parent) self.spin_steps = max(8, spin_steps) self.bar_width = .1 self.bar_height = .5 self.bar_roundness = max(0.0, min(1.0, bar_roundness)) self._fps = 24 self._current_step = 0 self._last_tick = time.time() self._step_interval = 1.0 / self.spin_steps self._update_timer = QTimer() self._update_timer.setInterval(1000 / self._fps) # noinspection PyUnresolvedReferences self._update_timer.timeout.connect(self.fade_colors) # --- Colors setup self.r_from = ticker_color.red() self.g_from = ticker_color.green() self.b_from = ticker_color.blue() self.r_to = fade_to_color.red() self.g_to = fade_to_color.green() self.b_to = fade_to_color.blue() self._lerps = list() for i in range(self.spin_steps): lerp_value = float(i) / (self.spin_steps - 1) self._lerps.append(lerp_value) self._lerps[0] = 1.0 self._spin_angle = 360 / self.spin_steps self.setMinimumSize(16, 16) def showEvent(self, event): self._update_timer.start() def hideEvent(self, event): self._update_timer.stop() def set_ticker_color(self, ticker_color): self.r_from = ticker_color.red() self.g_from = ticker_color.green() self.b_from = ticker_color.blue() def set_fade_to_color(self, fade_to_color): self.r_from = fade_to_color.red() self.g_from = fade_to_color.green() self.b_from = fade_to_color.blue() @Slot() def fade_colors(self): for i in range(len(self._lerps)): self._lerps[i] -= self._fps / 1000.0 tick = time.time() delta_t = tick - self._last_tick if delta_t >= self._step_interval: self._current_step += 1 if self._current_step >= self.spin_steps: self._current_step = 0 self._lerps[self._current_step] = 1.0 self._last_tick = tick self.update() def paintEvent(self, event): painter = QPainter(self) painter.setRenderHints(painter.Antialiasing) rect = self.geometry() short_side = min(rect.width(), rect.height()) if short_side return painter.setPen(Qt.NoPen) painter.translate(rect.width() / 2, rect.height() / 2) bar_width = short_side * self.bar_width round_radius = (bar_width / 2) * self.bar_roundness for i in range(self.spin_steps): painter.setBrush(self._get_interpolated_color(self._lerps[i])) paint_rect = QRect(-bar_width / 2, -short_side / 2, bar_width, (short_side * self.bar_height) / 2) if round_radius > 0: painter.drawRoundedRect(paint_rect, round_radius, round_radius) else: painter.drawRect(paint_rect) painter.rotate(self._spin_angle) def _get_interpolated_color(self, i): interp = min(1.0, max(0.0, i)) return QColor(int(((self.r_from - self.r_to) * interp) + self.r_to), int(((self.g_from - self.g_to) * interp) + self.g_to), int(((self.b_from - self.b_to) * interp) + self.b_to))
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto