如何使用QStackedWidget实现两个页面的翻转

这里提供一种实现思路

 

如何使用QStackedWidget实现页面翻转
/**
 * @brief The RotatingStackedWidget class 反转的stacked
 */
class RotatingStackedWidget : public QStackedWidget
{
    Q_OBJECT
    Q_PROPERTY( float rotateVal READ rotateVal WRITE setRotateVal) // TSC_IGNORE 
public:
    explicit RotatingStackedWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *event);  //paintEvent 绘制事件

public slots:
    void nextPage();  //nextPage 下一页
 
public:

    void rotate(int index);  //rotate index 跳转到索引页
    float rotateVal();  //rotateVal 旋转值
    void setRotateVal(float fl);  //setRotateVal 设置旋转值
    float startVal();   //setStartVal 动画开始值
    void setStartVal(float fl);  //setStartVal 设置动画开始值
    float endVal();            // 动画结束 
    void setEndVal(float fl);  //setEndVal 设置动画结束值

private slots:
    void valChanged(const QVariant& val);  //valChanged 旋转值改变了
    void animationDone();  //animDone 动画结束

private:
    float iRotateVal; //iRotateVal 旋转值
    bool isAnimating;  //isAnimating 旋转动画中
    int nextIndex;     //下一个索引页
    float fStartVal;  //动画开始值
    float fEndVal;   //动画结束值
};

#include
#include
#include

RotatingStackedWidget::RotatingStackedWidget(QWidget *parent):QStackedWidget(parent) //
{
    Q_UNUSED(parent);
    iRotateVal=0;
    fStartVal = 0;
    fEndVal = 180;
    nextIndex = -1;
    isAnimating=false;
    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
}

void RotatingStackedWidget::paintEvent(QPaintEvent *event)
{

    //绘制翻转效果,视觉上出现翻转现象
    if(isAnimating)
    {
        if(iRotateVal > 90)
        {
            QPixmap pixmap(widget(nextIndex)->size());
            widget(nextIndex)->render(&pixmap);
            QPainter painter(this);

            QTransform transform;
            transform.translate(width()/2, 0);
            transform.rotate(iRotateVal+180,Qt::YAxis);
            painter.setTransform(transform);
            painter.drawPixmap(-1*width()/2,0,pixmap);
        } else {
            QPixmap pixmap(currentWidget()->size());
            currentWidget()->render(&pixmap);
            QPainter painter(this);

            QTransform transform;
            transform.translate(width()/2, 0);
            transform.rotate(iRotateVal,Qt::YAxis);
            painter.setTransform(transform);
            painter.drawPixmap(-1*width()/2,0,pixmap);
        }
    } else {
        QWidget::paintEvent(event);
    }
}

void RotatingStackedWidget::nextPage()
{
    rotate((currentIndex() + 1) >= count() ? 0: (currentIndex() + 1));
}

void RotatingStackedWidget::rotate(int index)
{
    if(isAnimating) return;
    nextIndex = index;
    int offsetx=frameRect().width();
    int offsety=frameRect().height();
    widget(index)->setGeometry ( 0,  0, offsetx, offsety );
    QPropertyAnimation *animnow = new QPropertyAnimation(this,"rotateVal");
    animnow->setDuration(700);
    animnow->setEasingCurve(QEasingCurve::Linear);
    animnow->setStartValue(fStartVal);
    animnow->setEndValue(fEndVal);
    connect(animnow,SIGNAL(valueChanged(const QVariant&)),this,SLOT(valChanged(const QVariant&)));
    connect(animnow,SIGNAL(finished()),this,SLOT(animationDone()));
    currentWidget()->hide();
    isAnimating = true;
    animnow->start();
}

float RotatingStackedWidget::rotateVal()
{
    return iRotateVal;
}

void RotatingStackedWidget::setRotateVal(float fl)
{
    iRotateVal = fl;
}

void RotatingStackedWidget::valChanged(const QVariant& val)
{
    repaint();
}

void RotatingStackedWidget::animationDone()
{
    iRotateVal=0;
    isAnimating=false;
    widget(nextIndex)->show();
    widget(nextIndex)->raise();
    setCurrentWidget(widget(nextIndex));
    repaint();
}

float RotatingStackedWidget::startVal()
{
    return fStartVal;
}

void RotatingStackedWidget::setStartVal(float fl)
{
    fStartVal = fl;
}

float RotatingStackedWidget::endVal()
{
    return fEndVal;
}

void RotatingStackedWidget::setEndVal(float fl)
{
    fEndVal = fl;
}

class myFrame: public QDialog
 {
   Q_OBJECT
   public:
        myFrame(QWidget* parent=null);
        ~myFrame(){};
        void Switch2FrameTwo();
        void Switch2FrameOne();

   private:
       FrameOne  *m_pFrameOne;
       FrameTwo  *m_pFrameTwo;
       RotatingStackedWidget *m_pStackedWidget;
       QPushButton           *m_pPushButton;

 };

myFrame::myFrame(QWidget* parent):QDialog(parent)
{
    QHBoxLayout* pLayOut = new QHBoxLayout;
    pLayOut->setContentsMargins(16, 10, 16, 10); //设置布局左右顶底距离的位置
    m_pStackedWidget = new RotatingStackedWidget(this);
    m_pFrameOne = new FrameOne(this);
    m_pFrameTwo = new FrameTwo(this);
    m_pStackedWidget->addWidget(m_pFrameOne);            
    m_pStackedWidget->addWidget(m_pFrameTwo);    

     m_pPushButton = new QPushButton(this);
    
    QHBoxLayout* pWidgetLayout = new QHBoxLayout;
    pWidgetLayout->setContentsMargins(0, 0, 0, 0);
    pStackedWidgetLayout->addWidget(m_pStackedWidget);
       pStackedWidgetLayout->addWidget(m_pPushButton);
       this->setLayout(pStackedWidgetLayout);  //将布局加入到窗体


   QObject::connect(m_pPushButton, SIGNAL(clicked()), this, SLOT(Switch2FrameTwo()), Qt::UniqueConnection);  
   QObject::connect(m_pFrameTwo, SIGNAL(sigOK()), this, SLOT(Switch2FrameOne()), Qt::UniqueConnection);   //信号自己实现,窗体自己实现 


   
}


void myFrame::Switch2FrameTwo()
{
    m_pStackedWidget->setStartVal(0);  //翻转
    m_pStackedWidget->setEndVal(180);

    if (nullptr != m_pFrameOne)
    {
        //窗体做的一些事
    }

    m_pStackedWidget->rotate(1);
}

  void myFrame::Switch2FrameOne()
  {
    m_pStackedWidget->setStartVal(0);  //翻转
    m_pStackedWidget->setEndVal(-180);
    m_pStackedWidget->rotate(0);
  }

你可能感兴趣的:(C++,Qt,界面,c++,qt)