PyQt通過動畫實現平滑滾動的QScrollArea
前言
在之前的博客《如何在 pyqt 中實現平滑滾動的 QScrollArea》中,我們使用定時器和隊列實現了平滑滾動。但是實現代碼還是有一點復雜,所以這篇博客將使用 Qt 的動畫框架 QPropertyAnimation
來實現相同的功能。
實現過程
SmoothScrollBar
滾動過程其實就是改變 QScrollBar
的 value()
的過程,Qt 自帶的 QScrollArea
之所以無法平滑滾動,就是因為滾動時在 QScrollBar
的兩個 value()
之間進行跳變。如果我們能在兩個滾動值之間進行插值,就能實現平滑滾動了,這里通過重寫 setValue()
函數來啟動滾動動畫。
""" Smooth scroll bar """ scrollFinished = pyqtSignal() def __init__(self, parent=None): QScrollBar.__init__(self, parent) self.ani = QPropertyAnimation() self.ani.setTargetObject(self) self.ani.setPropertyName(b"value") self.ani.setEasingCurve(QEasingCurve.OutCubic) self.ani.setDuration(500) self.ani.finished.connect(self.scrollFinished) def setValue(self, value: int): if value == self.value(): return # stop running animation self.ani.stop() self.scrollFinished.emit() self.ani.setStartValue(self.value()) self.ani.setEndValue(value) self.ani.start() def scrollValue(self, value: int): """ scroll the specified distance """ value += self.value() self.scrollTo(value) def scrollTo(self, value: int): """ scroll to the specified position """ value = min(self.maximum(), max(self.minimum(), value)) self.setValue(value) def mousePressEvent(self, e): self.ani.stop() super().mousePressEvent(e) def mouseReleaseEvent(self, e): self.ani.stop() super().mouseReleaseEvent(e) def mouseMoveEvent(self, e): self.ani.stop() super().mouseMoveEvent(e)
SmoothScrollArea
最后需要將 QScrollArea
的默認滾動條替換為平滑滾動的 SmoothScrollBar
:
class SmoothScrollArea(QScrollArea): """ Smooth scroll area """ def __init__(self, parent=None): super().__init__(parent) self.hScrollBar = SmoothScrollBar() self.vScrollBar = SmoothScrollBar() self.hScrollBar.setOrientation(Qt.Horizontal) self.vScrollBar.setOrientation(Qt.Vertical) self.setVerticalScrollBar(self.vScrollBar) self.setHorizontalScrollBar(self.hScrollBar) def setScrollAnimation(self, orient, duration, easing=QEasingCurve.OutCubic): """ set scroll animation Parameters ---------- orient: Orient scroll orientation duration: int scroll duration easing: QEasingCurve animation type """ bar = self.hScrollBar if orient == Qt.Horizontal else self.vScrollBar bar.ani.setDuration(duration) bar.ani.setEasingCurve(easing) def wheelEvent(self, e): if e.modifiers() == Qt.NoModifier: self.vScrollBar.scrollValue(-e.angleDelta().y()) else: self.hScrollBar.scrollValue(-e.angleDelta().x())
測試
下面是一個簡單的圖片查看器測試程序:
import sys from PyQt5.QtCore import QEasingCurve, Qt from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QApplication, QLabel class Demo(SmoothScrollArea): def __init__(self): super().__init__() self.label = QLabel(self) self.label.setPixmap(QPixmap("shoko.jpg")) # customize scroll animation self.setScrollAnimation(Qt.Vertical, 400, QEasingCurve.OutQuint) self.setScrollAnimation(Qt.Horizontal, 400, QEasingCurve.OutQuint) self.horizontalScrollBar().setValue(1900) self.setWidget(self.label) self.resize(1200, 800) if __name__ == '__main__': app = QApplication(sys.argv) w = Demo() w.show() app.exec_()
最后
至此平滑滾動的實現方式就已介紹完畢了,更多自定義小部件可以參見 PyQt-Fluent-Widgets
到此這篇關于PyQt通過動畫實現平滑滾動的QScrollArea的文章就介紹到這了,更多相關PyQt QScrollArea內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
django authenticate用戶身份認證的項目實踐
Django的contrib.auth模塊中的authenticate()函數用于對用戶的憑據進行身份驗證,本文就來介紹一下django authenticate用戶身份認證的使用,具有一定的參考價值,感興趣的可以了解一下2023-08-08Flask的圖形化管理界面搭建框架Flask-Admin的使用教程
Flask-Admin是一個為Python的Flask框架服務的微型框架,可以像Django-Admin那樣為用戶生成Model層面的數據管理界面,接下來就一起來看一下Flask的圖形化管理界面搭建框架Flask-Admin的使用教程2016-06-06解決python和pycharm安裝gmpy2 出現ERROR的問題
這篇文章主要介紹了python和pycharm安裝gmpy2 出現ERROR的解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08使用Python來開發(fā)Markdown腳本擴展的實例分享
這篇文章主要介紹了使用Python來開發(fā)Markdown腳本擴展的實例分享,文中的示例是用來簡單地轉換文檔結構,主要為了體現一個思路,需要的朋友可以參考下2016-03-03Python3字符串的常用操作方法之修改方法與大小寫字母轉化
這篇文章主要介紹了Python3字符串的常用操作方法之修改方法與大小寫字母轉化,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09Python+Pygame實戰(zhàn)之炫舞小游戲的實現
提到QQ炫舞,可能很多人想到的第一個詞是“青春”?;腥婚g,這個承載了無數人回憶與時光的游戲品牌,已經走到了第十幾個年頭。今天小編就來給大家嘗試做一款簡單的簡陋版的小游戲——《舞動青春*炫舞》,感興趣的可以了解一下2022-12-12