如何在Qt中基于QPropertyAnimation创建按压宽度变化的动画按钮?
QPropertyAnimation 按钮宽度切换动画示例
以下是一个简单的实现:点击按钮后,宽度平滑缩至仅能容纳图标的尺寸,再次点击恢复原宽度。
C++ 实现(Qt Widgets)
头文件 MainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QPushButton> #include <QPropertyAnimation> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void toggleButtonWidth(); private: QPushButton *m_iconButton; QPropertyAnimation *m_widthAnimation; int m_originalWidth; bool m_isCollapsed; }; #endif // MAINWINDOW_H
源文件 MainWindow.cpp
#include "MainWindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_isCollapsed(false) { // 初始化带图标的按钮 m_iconButton = new QPushButton(this); m_iconButton->setIcon(QIcon(":/icons/your-icon.png")); // 替换为你的图标资源路径 m_iconButton->setIconSize(QSize(32, 32)); m_iconButton->setFixedHeight(40); m_originalWidth = 150; // 按钮初始宽度 m_iconButton->setFixedWidth(m_originalWidth); // 创建宽度动画:绑定按钮的"width"属性 m_widthAnimation = new QPropertyAnimation(m_iconButton, "width", this); m_widthAnimation->setDuration(300); // 动画持续300毫秒 m_widthAnimation->setEasingCurve(QEasingCurve::InOutQuad); // 平滑缓动曲线 // 绑定点击信号到切换函数 connect(m_iconButton, &QPushButton::clicked, this, &MainWindow::toggleButtonWidth); // 设置主窗口布局 setFixedSize(300, 100); m_iconButton->move(75, 30); } MainWindow::~MainWindow() { } void MainWindow::toggleButtonWidth() { m_isCollapsed = !m_isCollapsed; if (m_isCollapsed) { // 收缩到图标宽度 m_widthAnimation->setStartValue(m_iconButton->width()); m_widthAnimation->setEndValue(m_iconButton->iconSize().width()); } else { // 恢复原宽度 m_widthAnimation->setStartValue(m_iconButton->width()); m_widthAnimation->setEndValue(m_originalWidth); } m_widthAnimation->start(); }
PyQt6/PySide6 实现
import sys from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton from PyQt6.QtCore import QPropertyAnimation, QEasingCurve, Qt from PyQt6.QtGui import QIcon class MainWindow(QMainWindow): def __init__(self): super().__init__() self.is_collapsed = False # 初始化按钮 self.icon_button = QPushButton(self) self.icon_button.setIcon(QIcon("your-icon.png")) # 替换为你的图标路径 self.icon_button.setIconSize(Qt.Size(32, 32)) self.icon_button.setFixedHeight(40) self.original_width = 150 self.icon_button.setFixedWidth(self.original_width) # 创建宽度动画:绑定按钮的width属性 self.width_animation = QPropertyAnimation(self.icon_button, b"width") self.width_animation.setDuration(300) self.width_animation.setEasingCurve(QEasingCurve.Type.InOutQuad) # 绑定点击事件 self.icon_button.clicked.connect(self.toggle_button_width) # 设置窗口 self.setFixedSize(300, 100) self.icon_button.move(75, 30) def toggle_button_width(self): self.is_collapsed = not self.is_collapsed if self.is_collapsed: self.width_animation.setStartValue(self.icon_button.width()) self.width_animation.setEndValue(self.icon_button.iconSize().width()) else: self.width_animation.setStartValue(self.icon_button.width()) self.width_animation.setEndValue(self.original_width) self.width_animation.start() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
核心逻辑说明
- 绑定属性:
QPropertyAnimation的核心是绑定控件的一个可动画属性(这里是按钮的width),动画会自动修改该属性的值。 - 动画参数:
setDuration()设置动画时长,setEasingCurve()让过渡更自然(避免生硬的线性变化)。 - 状态切换:通过布尔变量记录按钮当前状态,点击时切换动画的起始/结束值,启动动画即可完成平滑过渡。
内容的提问来源于stack exchange,提问作者why
相关产品推荐
相关产品推荐

