0
点赞
收藏
分享

微信扫一扫

QT 滑屏窗口管理器(功能)

田妞的读书笔记 2022-04-07 阅读 59
c++qt5qt

QT 滑屏窗口管理器

Qt记述之路 _01


文章目录


前言

在我们QT使用过程中通常会遇到这样的场景(界面显示空间有限,而我们又需要显示很多内容),通常我们会使用到QTabWidget或者多个QWidget的 hide() 和 show()以及QStackedWidget窗口管理器, 来实现多窗口显示和管理,当然这些方法都能够很好的解决我们的问题,但是在美观和交互上就差了一些。而本博客就采用了QStackedWidget和QPropertyAnimation,以及QPainter实现了一个完美的模仿平板手机的滑动窗口管理。


一、功能

1.滑动翻页(模仿手机,平板)
2.点击切换页面
3.显示页标签
4.实现接口(方便使用)
5.封装为动态库

20220407_163925

在这里插入图片描述在这里插入图片描述


二、QStackedWidget是什么?

QStackedWidget类提供了一组小部件,其中每次只显示一个小部件,QStackedWidget可以用来创建一个类似于QTabWidget提供的用户界面。 它是一个方便的布局小部件,构建在qstackkedlayout类的顶部。 像qstackkedlayout一样,qstackkedwidget可以被构造和填充一些子部件(“页面”):

/*====================== QStackedWidget 使用 =======================*/
QWidget *firstPageWidget = new QWidget;
QWidget *secondPageWidget = new QWidget;
QWidget *thirdPageWidget = new QWidget;

QStackedWidget *stackedWidget = new QStackedWidget;
stackedWidget->addWidget(firstPageWidget);
stackedWidget->addWidget(secondPageWidget);
stackedWidget->addWidget(thirdPageWidget);

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(stackedWidget);
setLayout(layout);
/*=================================================================*/

三、那么正文来了!!!

1.事件处理

判断鼠标点击和移动事件(需要考虑误触碰、拖拽时间、是否翻页):

// 事件过滤器
bool PageWidget::eventFilter(QObject *obj, QEvent *evt)
{
    QMouseEvent *mouse =  static_cast<QMouseEvent *>(evt);
    // 计算参数
    int _width = this->width();         // 计算边框大小

    if(m_Widgets && m_Widgets->count() > 0 && mouse && m_PriorAnimation  && m_PriorAnimation->state() == QAbstractAnimation::Stopped)
    {
        if(mouse->type()==QEvent::MouseButtonPress)
        {
            m_pressMSec = QDateTime::currentDateTime().toMSecsSinceEpoch();     // 记录按下的时间
            press_x = mouse->globalX();
            press_y = mouse->globalY();
        }
        else if(mouse->type()==QEvent::MouseButtonRelease)
        {
            if((QDateTime::currentDateTime().toMSecsSinceEpoch() -  m_pressMSec) > 300 && qAbs(mouse->globalX() - press_x) < _width / 3)
                e_SwitchFlag = SWITCH_NONE;
            if(qAbs(press_x - mouse->globalX()) > 3)
                SmoothAnimationStart();
        }
        else if(mouse->type()==QEvent::MouseMove)
        {
            m_MovePoint = mouse->globalPos();

            // 判断向左还是向右滑(并且还有±5的防止误触限制)
            if(press_x - mouse->globalX() < -5)
            {
                e_SwitchFlag = SWITCH_PRE;
                if(m_Widgets->currentIndex() - 1 >= 0)
                    m_LastWidget = m_Widgets->widget(m_Widgets->currentIndex() - 1);
                else
                    m_LastWidget = nullptr;
            }
            else if(press_x - mouse->globalX() > 5)
            {
                e_SwitchFlag = SWITCH_NEXT;
                if(m_Widgets->currentIndex() + 1 < m_Widgets->count())
                    m_LastWidget = m_Widgets->widget(m_Widgets->currentIndex() + 1);
                else
                    m_LastWidget = nullptr;
            }
            else
            {
                e_SwitchFlag = SWITCH_NONE;
                m_LastWidget = nullptr;
            }

            // 移动位置
            SmoothMove();
        }
    }
    return QWidget::eventFilter(obj,evt);
}

2.标签绘制

// 绘制标签
void LabelPage::DrawLabel(QPainter &painter)
{
    if(PageWidgetSumIndex <= 1)
        return;

    // 计算参数
    int _ypos;

    painter.setRenderHint(QPainter::Antialiasing,true);
    for(int i = 0; i < PageWidgetSumIndex; i++)
    {
        if(i == PageWidgetCurrentIndex)
            painter.setBrush(m_LabelColor);
        else
            painter.setBrush(QColor(220,220,220,150));
        if(Label_Dot == e_style)
        {
            m_Length = 10;
            m_movedistance = 8;
            _ypos = m_Length/2;
            painter.drawEllipse(QPointF(m_Length/2 + (i*m_movedistance) + (i*m_Length), _ypos),m_Length/2,m_Length/2);
        }
        else if(Label_Bar_Type == e_style)
        {
            m_Length = 30;
            m_movedistance = 5;
            _ypos = m_Length/2;
            painter.drawRoundedRect(QRectF((i*m_movedistance) + (i*m_Length), _ypos, m_Length, m_Length/7),m_Length/12, m_Length/12);

        }
    }
    m_sumlength = PageWidgetSumIndex * m_Length + (PageWidgetSumIndex-1) * m_movedistance;


    if(Label_Dot == e_style)
        move(m_size.width()/2 - m_sumlength/2, m_size.height() - (m_Length * 3.5));
    else if(Label_Bar_Type == e_style)
        move(m_size.width()/2 - m_sumlength/2, m_size.height() - (m_Length * 1.5));

    resize(m_sumlength, m_Length);
}

总结

实现逻辑就是用QStackedWidget来管理我们的窗口,用QPropertyAnimation(动画类)来实现翻页效果,便签页就用Qpainter绘制(注意:这里面会出现一个问题,就是绘制的标签会被窗口挡住,这个时候就可以用一个新的QWidget来绘制标签,然后把这个QWidget置顶就OK!),纯属拙见,欢迎大家指教…

举报

相关推荐

桌面窗口管理器

【QT】QT布局管理器

Qt布局管理器

Qt--ipad滑屏效果

Qt 布局管理器使用

0 条评论