############################################################################ ## ## Copyright (C) 2020 The Qt Company Ltd. ## Contact: https://www.qt.io/licensing/ ## ## This file is part of the Qt for Python examples of the Qt Toolkit. ## ## $QT_BEGIN_LICENSE:BSD$ ## Commercial License Usage ## Licensees holding valid commercial Qt licenses may use this file in ## accordance with the commercial license agreement provided with the ## Software or, alternatively, in accordance with the terms contained in ## a written agreement between you and The Qt Company. For licensing terms ## and conditions see https://www.qt.io/terms-conditions. For further ## information use the contact form at https://www.qt.io/contact-us. ## ## BSD License Usage ## Alternatively, you may use this file under the terms of the BSD license ## as follows: ## ## "Redistribution and use in source and binary forms, with or without ## modification, are permitted provided that the following conditions are ## met: ## * Redistributions of source code must retain the above copyright ## notice, this list of conditions and the following disclaimer. ## * Redistributions in binary form must reproduce the above copyright ## notice, this list of conditions and the following disclaimer in ## the documentation and/or other materials provided with the ## distribution. ## * Neither the name of The Qt Company Ltd nor the names of its ## contributors may be used to endorse or promote products derived ## from this software without specific prior written permission. ## ## ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ## ## $QT_END_LICENSE$ ## ############################################################################ from PySide6.QtCore import QBasicTimer, Property from PySide6.QtGui import QColor, QFontMetrics, QPainter, QPalette from PySide6.QtWidgets import QWidget class WigglyWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) self._step = 0 self._text = "" self.setBackgroundRole(QPalette.Midlight) self.setAutoFillBackground(True) new_font = self.font() new_font.setPointSize(new_font.pointSize() + 20) self.setFont(new_font) self._timer = QBasicTimer() def isRunning(self): return self._timer.isActive() def setRunning(self, r): if r == self.isRunning(): return if r: self._timer.start(60, self) else: self._timer.stop() def paintEvent(self, event): if not self._text: return sineTable = [0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38] metrics = QFontMetrics(self.font()) x = (self.width() - metrics.horizontalAdvance(self.text)) / 2 y = (self.height() + metrics.ascent() - metrics.descent()) / 2 color = QColor() painter = QPainter(self) for i in range(len(self.text)): index = (self._step + i) % 16 color.setHsv((15 - index) * 16, 255, 191) painter.setPen(color) dy = (sineTable[index] * metrics.height()) / 400 c = self._text[i] painter.drawText(x, y - dy, str(c)) x += metrics.horizontalAdvance(c) def timerEvent(self, event): if event.timerId() == self._timer.timerId(): self._step += 1 self.update() else: QWidget.timerEvent(event) def text(self): return self._text def setText(self, text): self._text = text running = Property(bool, isRunning, setRunning) text = Property(str, text, setText)