1. 程式人生 > >[Qt]介面顯示效果之卷軸

[Qt]介面顯示效果之卷軸

Qt介面的淡入淡出效果大家可能都有所接觸,不過能不能以“卷軸”的形式慢慢呈現出來呢,我這裡先呈上兩個效果

展開過程


定格的時候

上原始碼,如果不需要就直接略過哈

標頭檔案:

#ifndef QREELWIDGET_H
#define QREELWIDGET_H

#include <QTimeLine>
#include <QWidget>
#include <QPainter>

class QReelWidget : public QWidget
{
    Q_OBJECT

public:
    QReelWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent*);
    void setOriPos(const QPoint&);
    void setOriSize(const QSize&);
    void showExpan();

private slots:
    void onShow();
    void onExpansion();

private:
    bool bFinally;
    QPoint oriPos;
    QSize  oriSize;
    QTimeLine animaShow;
    QTimeLine animaExpan;
};

#endif // QREELWIDGET_H

原始檔:
#include "QFadeWidget.h"

QReelWidget::QReelWidget(QWidget *parent) :
    QWidget(parent)
{
    oriSize = QSize(0, 0);
    connect(&animaShow, SIGNAL(frameChanged(int)), SLOT(onShow()));
    connect(&animaExpan, SIGNAL(frameChanged(int)), SLOT(onExpansion()));
    animaShow.setFrameRange(0, 100);
    animaShow.setDuration(100); //平移過程持續時間
    animaShow.setCurveShape(QTimeLine::EaseInCurve); //先慢後快
    animaExpan.setFrameRange(0, 100);
    animaExpan.setDuration(500); //展開過程持續時間
    animaExpan.setCurveShape(QTimeLine::LinearCurve); //勻速
}

void QReelWidget::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);
    QPen p(QColor(179,196,204)); //畫邊框用,顏色深一點邊框更明顯,效果會更好一些
    p.setWidth(2);
    painter.setPen(p);

    QLinearGradient linearGradient(QPointF(0, 0), QPointF(0, rect().height()));
    linearGradient.setColorAt(0, QColor(236,240,244));
    linearGradient.setColorAt(1, QColor(203,215,221));
    linearGradient.setSpread(QGradient::PadSpread);

    painter.save();
    QPainterPath path;
    /* 窗體圓角設定
     * 底部留25高度畫“卷軸”
     * 注意不能用 addRoundRect方法,否則圓角弧度會隨窗體大小自動調整,這裡要的是絕對弧度 */
    path.addRoundedRect(QRect(rect().topLeft(),QPoint(rect().right(),rect().bottom()-25)),8,8);
    painter.fillPath(path,QBrush(linearGradient));
    painter.drawPath(path);
    painter.restore();
    if(bFinally) { //定格,即最終呈現的時候
        painter.save();
        //因為窗體左下角有一個弧度,還要考慮曲線外留下的空白區域,先“填補”它
        QRect r(0,height()-33,15,16);
        painter.fillRect(r,QColor(203,215,221));
        painter.drawLine(r.topLeft(), r.bottomLeft());

        painter.restore();
        //用貝塞爾曲線填充
        QPoint startPos(20,height()-25);
        QPoint endPos(20,startPos.y()+25);
        QPainterPath path1(startPos);
        //貝塞爾曲線的兩個控制點可能沒那麼精確,大家可以參考貝塞爾曲線演算法做到更精確的控制,我這就不贅述了
        path1.cubicTo(QPoint(0,startPos.y()), QPoint(-15,startPos.y()+8), endPos);
        //閉合曲線區域
        path1.closeSubpath();
        painter.fillPath(path1, QColor(43,43,43));
        painter.drawPath(path1);
    }
    else { //動畫的時候
        painter.save();
        //同上面一樣,先“填補”窗體左下角的空白區域

        /* 注意這裡的橢圓高度控制為15,底部給定格的時候留下一定區域
         * 因為定格的時候“捲筒”要展開 */
        QRect r(0,height()-33,20,15);
        painter.fillRect(r,QColor(203,215,221));
        //畫三條邊框線
        painter.drawLine(r.topLeft(), r.bottomLeft());
        painter.drawLine(QPoint(20,height()-25), r.bottomRight());
        painter.drawLine(QPoint(10,height()-25), QPoint(20,height()-25));

        painter.restore();
        //用橢圓填充
        QPainterPath path1;
        path1.addEllipse(0,height()-25,20,15);
        painter.fillPath(path1, QColor(43,43,43));
        painter.drawPath(path1);
    }
}

void QReelWidget::onShow()
{
    /* 顯示Widget的時候首先按幀數逐漸平移到指定位置oriPos
     * 我這裡x方向總共移動10,y方向移動60,大家可以根據需要自己控制
     * 若不需要平移的效果大可直接忽略 */
    int indexFrame = animaShow.currentFrame();
    move(oriPos.x()+10/100.0*(100-indexFrame), oriPos.y()+60/100.0*(100-indexFrame));
    if(indexFrame >= 99) //平移完後開始逐漸展開
        animaExpan.start();
}
void QReelWidget::onExpansion()
{
    /* 展開過程,oriSize為Widget的原始尺寸
     * 展開過程寬度至少為20,因為“卷軸”部分的寬度為20 */
    int indexFrame = animaExpan.currentFrame();
    resize(20+(oriSize.width()-20)/100.0*indexFrame, oriSize.height());
    if(indexFrame >= 99) { //最終定格
        bFinally = true;
    }
}
//展開顯示
void QReelWidget::showExpan()
{
    bFinally = false;
    resize(20,height()); //最初保持“卷軸”部分的寬度
    move(oriPos.x()+10,oriPos.y()+60);
    show();
    animaShow.stop();
    animaExpan.stop();
    animaShow.start();
}
//設定原始左上角座標
void QReelWidget::setOriPos(const QPoint& p)
{
    this->oriPos = p;
}
//設定原始尺寸
void QReelWidget::setOriSize(const QSize& s)
{
    this->oriSize = s;
}

呼叫的時候肯定要先繼承QReelWidget,然後一定要先設好原始位置和原始尺寸,如:

testWidget * tw = new testWidget;
tw->setOriPos(QPoint(100, 100));
tw->setOriSize(QSize(400,300));
tw->showExpan();

本文涉及貝塞爾曲線,有興趣的朋友可查閱相關資料進一步瞭解

相關推薦

[Qt]介面顯示效果卷軸

Qt介面的淡入淡出效果大家可能都有所接觸,不過能不能以“卷軸”的形式慢慢呈現出來呢,我這裡先呈上兩個效果 展開過程 定格的時候 上原始碼,如果不需要就直接略過哈 標頭檔案: #ifndef QREELWIDGET_H #define QREELWIDGET_H #i

ARM開發板OK6410移植opencv-2.4.7庫qt介面顯示(附加各種問題解決方案)

轉載:http://blog.csdn.net/jiebaoabcabc/article/details/22935185          經過了昨天一天苦逼的研究opencv原始碼、arm-linux編譯器工作原理和堅持不懈的make,我終於移植成功了opencv-2

Android UI介面顯示效果——集合(一)

1:UI介面 — 帶圓角的背景樣式在drawable資料夾下新建xml,內容如下 :1> 帶填充色的圓角樣式<?xml    version="1.0"    encoding="utf-8

ffmpeg解碼RTSP/TCP視訊流H.264(QT介面顯示視訊畫面)

我用的ffmpeg版本為 ffmpeg-2.1.8.tar.bz2 版本低了恐怕有些標頭檔案和API找不到。 在Linux下解壓後編譯,Linux下編譯很簡單,我這裡生成的動態庫: ./configure –enable-shared make 就

QT介面顯示實時時間

#include "BV.h" #include "QtCore" BV::BV(QWidget *parent) : QMainWindow(parent) {ui.setupUi(this);void nowtime();QTimer *timer = new QT

Qt QQ系統表情—實現動態顯示效果

簡述 在Qt 之 QQ系統表情(五) 中 我們實現了自定義系統表情視窗,這一篇將簡單介紹如何實現QQ聊天介面中小表情視窗切換至正常表情視窗的動畫效果。 先看看QQ的效果: 當滑鼠懸浮在表情按鈕之上顯示小表情視窗,點選動態顯示正常表情視窗,再點選隱

Qt彈出介面顯示在父視窗中間

彈出介面顯示在主視窗中間博主暫時只知道兩種方式第一種:    建立新的對話方塊時把父視窗的指標傳遞給對話方塊    QNewDiglog *dlg  = new QNewDiglog(parent);    dlg->show();    彈出的對話方塊就會自動顯示在父

JS實例選項卡效果,實現點擊對應的顯示效果

http body auto 100% itl elements lis style char 1 <head> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"

Qt|Linux工作筆記-非同步呼叫ping命令,重定向獲取資訊,介面顯示

邏輯: 1.使用QProcess在開執行緒前設定輸出檔案【setStandardOutputFile】; 2.開一個執行緒,去專門呼叫shell命令,比如ping; 3.Qt讀取重定向檔案,進行介面顯示;   程式執行截圖如下:   原始碼如

高仿網易評論列表效果介面生成

                前兩節我們分別分析了網易評論列表介面和生成一些我們需要的測試資料,生成測試資料那段如果大家看著看得頭疼沒關係,直接調業務物件中的方法生成資料即可不必理會我是怎麼處理的,接下來的對於大家來說才是讓各位感興趣的東西。介面分析了、資料也有了,那我們如何實現這樣的一個介面呢?首先我們來

jQuery效果隱藏與顯示、淡入淡出、滑動、回撥

1. 隱藏與顯示 通過 jQuery,可以使用 hide() 和 show() 方法來隱藏和顯示 HTML 元素,可以使用 toggle() 方法來切換 hide() 和 show() 方法。 語法: $(selector).hide(speed,callback); $(s

QT+VS+Opencv製作介面顯示圖片

      前面說了怎麼配置VS+QT+opencv,現在記錄一下如何開始用VS+QT+opencv做介面顯示圖片的小例子。(配置可見之前的部落格 QT5.9.6和VS2015的配置使用) 1.新建工程       開啟VS2015,檔案 -> 新建 -> 專

Android 實現多頁介面左右滑動切換效果入門+進階 (ViewPager+PagerAdapter)

前一篇已經簡單介紹了ViewPager實現介面左右滑動的簡單實現方法。可以該方法實現方式雖說簡單,但是存在很大的問題——介面雖然隨左右滑動而切換了,但是實際所在的操作類還同一個(即在同一個Activity中),這一問題將導致程式的邏輯變得複雜時,介面控制元件變多時該Activity中實現的程式碼迅速的增加,最

qt學習qt介面控制小烏龜運動(二)

PS:小編也是新手,在做介面時也走了很多彎路,很多博主寫的不是很明確,所以小編記錄了自己製作的全過程,希望對初學者有用,共同進步。 1.新建工作空間catkin_new,並建立src包,。 2.新建ROS workspace ,儲存在src資料夾內,開啟工程是直

Android 使用ViewPager實現類似gallery畫廊的效果(畫廊效果ViewPager顯示多個圖片)

這個畫廊的效果利用到了View的clipChildren屬性,我們在這裡要把ViewPager以及它的父窗體都設定為false,如下: android:clipChildren="false

qt介面視窗旋轉90度顯示

【1、與qt程式顯示文字大小有關的兩項】 export QWS_DISPLAY=LinuxFB:mmWidth200:mmHeight100:0   //輸出裝置為Linux framebuffer,尺寸定義(尺寸定義與文字大小有直接關係) export QWS_SIZE=480x272   //螢幕大

Linux學習筆記QT介面操作板子LED

Linux學習筆記之小目標一:用QT介面操作板子LED 一、目標:用QT繪製一個介面,點選開按鈕,板子LED點亮,點選關按鈕,LED熄滅 二、設計知識點:Linux底層IO驅動,核心程式設計,QT程式設計 三、程式碼部分 1、驅動程式碼 qt-led.c

Qt如何顯示一個動態的變數或者說定時重新整理介面

1.先說明下,題目有兩個關鍵詞,因為我之前搜 的就是展示一個動態的變數,搜了半天,基本上沒啥有用的.後面的關鍵詞是 再搜前面的關鍵詞的時候 找到的似乎類似的 方面.恩,後面關鍵詞 是可以解決前面的問題. 希望搜前面的關鍵詞的童鞋 可以關聯到我這篇部落格. 2.我要做的是,

VGA HDMI DVI DP介面是什麼顯示器顯示不清晰我該怎麼辦

VGA介面 先說VGA介面(簡述屬於淘汰邊緣產品對於2017年來說重點是VGA傳輸模擬訊號) VGA介面共有15針,分成3排,每排5個孔,是顯示卡上應用 VGA介面是大家所熟知的一個視訊模擬傳輸介面,從上世紀80年代被推出以來,已經發展了20多年了,很多領域已經相當成熟 最為廣泛的介面型別,絕大

Qt程式設定介面顯示在螢幕中央(包括多屏機的處理)

        最近養了一隻笨笨的狗子,感覺和養個孩子似的,心累...         下面要開始我們的正題了,咳咳。最近在程式中遇到一個問題,在網上搜了很久也沒搜到類似的問題,不過還是搜到了幾篇相關的博文,才解決了,所以特來把這個問題以及解決方式寫在這裡,方便後期遇到類似