国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動

這篇具有很好參考價(jià)值的文章主要介紹了【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

OpenCV實(shí)現(xiàn)視頻播放器,其思路大致就是在線程中使用OpenCV中的VideoCapture循環(huán)讀取本地視頻的每一幀Mat,然后發(fā)送到界面轉(zhuǎn)換成QImage進(jìn)行顯示,而進(jìn)度條拖動則用到了VideoCapture中的set函數(shù),進(jìn)度條則是使用Qslider;并且通過自定義新的進(jìn)度條類實(shí)現(xiàn)點(diǎn)擊跳轉(zhuǎn)功能;

效果:

【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動

1.進(jìn)行播放,線程循環(huán)讀取視頻幀并計(jì)數(shù)當(dāng)前幀數(shù),把Mat幀和當(dāng)前幀數(shù)通過信號發(fā)送到窗口

窗口中創(chuàng)建線程,然后點(diǎn)擊播放時(shí)在調(diào)用start啟動線程;

void videothread::run()
{
    while(stop==false)//線程運(yùn)行和停止  卡住線程 暫停時(shí)不退出線程
    {
        while(isrun==true)//視頻運(yùn)行和暫停
        {
            if(cap.read(frame))//捕獲視頻幀
            {
                this->currentFramecount++;
                cvtColor(frame, frame, CV_BGR2RGB);//opencvBGR格式轉(zhuǎn)成Image用到的RGB
                emit sendFrame(currentFramecount,frame);//發(fā)送幀數(shù)據(jù)

            }
            msleep(40);//延時(shí)

        }
    }

    cap.release();//釋放打開的視頻
}

2.獲取當(dāng)前幀數(shù)設(shè)置進(jìn)度條當(dāng)前值

【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動

?3.通過VideoCapture中的get方法獲取視頻總幀數(shù)并保存

    if(cap.open(filename));//創(chuàng)建視頻對象
    {
        this->allFramecount=cap.get(CAP_PROP_FRAME_COUNT);//獲取視頻文件中的總幀數(shù)
        this->fps=int(round(cap.get(CAP_PROP_FPS)));//獲取視頻幀率
    }

?4.設(shè)置進(jìn)度條取值范圍,即0-總幀數(shù)

    ui->horizontalSlider->setRange(0,pthread->getVideoAllFramecount());//設(shè)置進(jìn)度條取值范圍
    ui->horizontalSlider->setSingleStep(1);//設(shè)置單步長為1
    ui->label_4->setText(QString::number(pthread->getVideoAllFramecount()));//設(shè)置總幀數(shù)

接下來就是進(jìn)度條拖動,在知道如何做之前,我們要先了解Qslider的幾個(gè)信號,我們拖動時(shí)就需要用到點(diǎn)擊、滑動和釋放信號

Qslider常用信號

1.移動滑動條時(shí)發(fā)出的信號

void sliderMove(int value);

2.點(diǎn)擊滑動條時(shí)所發(fā)出的信號

void sliderPressed();

?3.釋放時(shí)所發(fā)出的信號

void sliderReleased();

5.首先是拖動進(jìn)度條,拖動的時(shí)候先把播放的視頻暫停

就是停止循環(huán)讀幀

void Widget::on_horizontalSlider_sliderMoved(int position)//進(jìn)度條拖動
{
    pthread->pauseThread();//播放暫停
}
void videothread::pauseThread()//這兩個(gè)函數(shù)用于確保是在運(yùn)行情況下才能切換狀態(tài)
{
    if(this->isRunning()&&this->isrun==true)//當(dāng)前線程運(yùn)行且視頻運(yùn)行
    {
        this->isrun=false;
    }
}

6.釋放進(jìn)度條

獲取拖動后的進(jìn)度條的值,然后通過set中的CV_CAP_PROP_POS_FRAMES進(jìn)行設(shè)置

void Widget::on_horizontalSlider_sliderReleased()//釋放進(jìn)度條
{
    //ui->horizontalSlider->value();獲取當(dāng)前進(jìn)度條值
    pthread->setCurrentFrame(ui->horizontalSlider->value());
    pthread->resumeThread();//播放繼續(xù) 設(shè)置為true

}
void videothread::setCurrentFrame(int value)
{
    this->currentFramecount=value;//當(dāng)前幀數(shù)
    cap.set(CV_CAP_PROP_POS_FRAMES,currentFramecount);//進(jìn)度條跳轉(zhuǎn)對應(yīng)幀
}

7.點(diǎn)擊進(jìn)度條,重寫一個(gè)進(jìn)度條類

因?yàn)橄到y(tǒng)自帶的進(jìn)度條點(diǎn)擊時(shí)只能移動一小段,不能實(shí)現(xiàn)點(diǎn)哪就移動到哪,所以我們要自己重寫一個(gè)進(jìn)度條類,然后在ui中提升為重寫的進(jìn)度條

【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動

?文章來源地址http://www.zghlxwxcb.cn/news/detail-400448.html

【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動

完整源碼:

?自定義進(jìn)度條

#ifndef NEWQSLIDER_H
#define NEWQSLIDER_H

#include <QWidget>
#include <QSlider>
#include <QMouseEvent>
class newqslider : public QSlider
{
    Q_OBJECT
public:
    explicit newqslider(QWidget *parent = 0);
    void mousePressEvent(QMouseEvent *ev);
signals:
    void costomSliderClicked();//自定義的鼠標(biāo)單擊信號,用于捕獲并處理
public slots:
};

#endif // NEWQSLIDER_H
#include "newqslider.h"

newqslider::newqslider(QWidget *parent) : QSlider(parent)
{    
}
/*****************************************************************
* 函數(shù)名稱:mousePressEvent(QMouseEvent *ev)
* 功能描述:重寫鼠標(biāo)點(diǎn)擊事件,實(shí)現(xiàn)進(jìn)度條點(diǎn)擊哪跳到哪
* 參數(shù)說明: 無
* 返回值:   無
******************************************************************/
void newqslider::mousePressEvent(QMouseEvent *ev)
{
    //先調(diào)用父類的鼠標(biāo)點(diǎn)擊處理事件,這樣可以不影響拖動的情況
    QSlider::mousePressEvent(ev);
    //獲取鼠標(biāo)的位置,這里并不能直接從ev中取值(因?yàn)槿绻峭蟿拥脑?,鼠?biāo)開始點(diǎn)擊的位置沒有意義了)
    double pos = ev->pos().x() / (double)width();
    setValue(pos * (maximum() - minimum()) + minimum());
    //發(fā)送自定義的鼠標(biāo)單擊信號
    emit costomSliderClicked();
}

?線程類

#ifndef VIDEOTHREAD_H
#define VIDEOTHREAD_H

#include <QObject>
#include <QThread>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <QDebug>
#include <QDateTime>
using namespace  std;
using namespace  cv;
class videothread : public QThread
{
    Q_OBJECT
public:
    videothread(char*filename);
    void run();
    int getVideoAllFramecount();//獲取視頻總幀數(shù)
    void setCurrentFrame(int value);//設(shè)置當(dāng)前進(jìn)度條

    bool getStop() const;
    void setStop(bool value);//設(shè)置視頻結(jié)束標(biāo)識
    bool getIsrun() const;
    void setIsrun(bool value);

    void pauseThread();//暫停
    void resumeThread();//繼續(xù)
    void stopThread();//停止

signals:
    void sendFrame(int currentFrame,Mat frame);//當(dāng)前幀和 幀數(shù)
private:
    VideoCapture cap;//視頻對象
    Mat frame;
    int currentFramecount;//視頻當(dāng)前幀數(shù)
    int allFramecount;//總幀數(shù)
    int fps;//視頻幀率
    int videoWriterFrame;//錄制視頻幀
    bool stop;//線程結(jié)束標(biāo)識位
    bool isrun;//視頻暫停標(biāo)識位

};

#endif // VIDEOTHREAD_H

?

#include "videothread.h"

videothread::videothread(char*filename)
{
    this->stop = false;
    this->isrun =false;
    this->currentFramecount=0;
    this->videoWriterFrame=0;
    if(cap.open(filename));//創(chuàng)建視頻對象
    {
        this->allFramecount=cap.get(CAP_PROP_FRAME_COUNT);//獲取視頻文件中的總幀數(shù)
        this->fps=int(round(cap.get(CAP_PROP_FPS)));//獲取視頻幀率
    }
}

void videothread::run()
{
    while(stop==false)//線程運(yùn)行和停止  卡住線程 暫停時(shí)不退出線程
    {
        while(isrun==true)//視頻運(yùn)行和暫停
        {
            if(cap.read(frame))//捕獲視頻幀
            {
                this->currentFramecount++;
                cvtColor(frame, frame, CV_BGR2RGB);//opencvBGR格式轉(zhuǎn)成Image用到的RGB
                emit sendFrame(currentFramecount,frame);//發(fā)送幀數(shù)據(jù)

            }
            msleep(40);//延時(shí)

        }
    }

    cap.release();//釋放打開的視頻
}

int videothread::getVideoAllFramecount()
{
    return allFramecount;
}


void videothread::setStop(bool value)
{
    stop = value;
}

void videothread::setCurrentFrame(int value)
{
    this->currentFramecount=value;//當(dāng)前幀數(shù)
    cap.set(CV_CAP_PROP_POS_FRAMES,currentFramecount);//進(jìn)度條跳轉(zhuǎn)對應(yīng)幀
}

bool videothread::getIsrun() const
{
    return isrun;
}

void videothread::setIsrun(bool value)
{
    isrun = value;
}

void videothread::pauseThread()//這兩個(gè)函數(shù)用于確保是在運(yùn)行情況下才能切換狀態(tài)
{
    if(this->isRunning()&&this->isrun==true)//當(dāng)前線程運(yùn)行且視頻運(yùn)行
    {
        this->isrun=false;
    }
}

void videothread::resumeThread()
{
    if(this->isRunning()&&this->isrun==false)//當(dāng)前線程運(yùn)行且視頻暫停
    {
        this->isrun=true;
    }
}

void videothread::stopThread()
{
    if(this->isRunning())//當(dāng)前線程運(yùn)行
    {
       this->stop=true;//結(jié)束線程
       //msleep(10);

        this->terminate();
    }
}


bool videothread::getStop() const
{
    return stop;
}

?窗口類

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSlider>
#include "videothread.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void paintEvent(QPaintEvent *e);

public slots:
    void receiveFrame(int currentFrame,Mat frame);
private slots:
    void on_pushButton_clicked();

    void sliderClickedSlot();//點(diǎn)擊進(jìn)度條信號槽

    void on_horizontalSlider_sliderReleased();

    void on_horizontalSlider_sliderMoved(int position);

    void on_pushButton_pause_clicked();

    void on_pushButton_pause_2_clicked();

    void on_pushButton_pause_3_clicked();
private:
    Ui::Widget *ui;
    videothread *pthread;

    int receiveCurrentFramecount;
    QImage img1;
    bool isend;
};

#endif // WIDGET_H

?

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    this->receiveCurrentFramecount=0;
    this->isend=false;
    ui->setupUi(this);

    pthread=new videothread("carMove.mp4");
    //第五個(gè)參數(shù)采用Qt::BlockingQueuedConnection   信號發(fā)出后發(fā)送線程阻塞,直到槽函數(shù)執(zhí)行完畢,繼續(xù)發(fā)送下一條信號
    connect(pthread,SIGNAL(sendFrame(int,Mat)),this,SLOT(receiveFrame(int,Mat)),Qt::BlockingQueuedConnection);//接收每一幀Mat
    //connect(pthread,SIGNAL(endPlayVideo()),this,SLOT(setPlayEndSlot()),Qt::BlockingQueuedConnection);
    connect(ui->horizontalSlider,SIGNAL(costomSliderClicked()),this,SLOT(sliderClickedSlot()));//點(diǎn)擊進(jìn)度條信號槽
    ui->horizontalSlider->setRange(0,pthread->getVideoAllFramecount());//設(shè)置進(jìn)度條取值范圍
    ui->horizontalSlider->setSingleStep(1);//設(shè)置單步長為1
    ui->label_4->setText(QString::number(pthread->getVideoAllFramecount()));//設(shè)置總幀數(shù)
}

Widget::~Widget()
{
    delete ui;
}

void Widget::receiveFrame(int currentFrame, Mat frame)
{
    this->receiveCurrentFramecount=currentFrame;
    this->img1 = QImage(frame.data,frame.cols,frame.rows,QImage::Format_RGB888);
    this->img1 = this->img1.scaled(ui->label->width(),ui->label->height());

    ui->horizontalSlider->setValue(this->receiveCurrentFramecount);//設(shè)置當(dāng)前進(jìn)度條取值
    ui->label_2->setText(QString::number(this->receiveCurrentFramecount));//設(shè)置當(dāng)前幀數(shù)
    update();
}

void Widget::setPlayEndSlot()
{
    pthread->setStop(true);//播放完畢 設(shè)置為true
}

void Widget::on_pushButton_clicked()
{
    pthread->start();
    pthread->setIsrun(true);//視頻開始

}
void Widget::on_pushButton_pause_clicked()//暫停
{
    if(pthread->getIsrun()==false&&pthread->isRunning())//暫停狀態(tài)且線程運(yùn)行
    {
        pthread->resumeThread();//修改為播放狀態(tài)
        ui->pushButton_pause->setText("暫停播放");
    }
    else if(pthread->getIsrun()==true&&pthread->isRunning())//播放狀態(tài)
    {
        pthread->pauseThread();;//視頻暫停
        ui->pushButton_pause->setText("繼續(xù)播放");
    }
}
void Widget::paintEvent(QPaintEvent *e)
{
    ui->label->setPixmap(QPixmap::fromImage(this->img1));
}

void Widget::sliderClickedSlot()//點(diǎn)擊進(jìn)度條 信號槽
{
    //自定義鼠標(biāo)點(diǎn)擊信號,可以實(shí)現(xiàn)點(diǎn)哪 跳轉(zhuǎn)到哪
    qDebug()<<"點(diǎn)擊了進(jìn)度條";
    pthread->pauseThread();//播放暫停
    pthread->setCurrentFrame(ui->horizontalSlider->value());
    pthread->resumeThread();//播放繼續(xù) 設(shè)置為true
}

void Widget::on_horizontalSlider_sliderReleased()//釋放進(jìn)度條
{
    //ui->horizontalSlider->value();獲取當(dāng)前進(jìn)度條值
    pthread->setCurrentFrame(ui->horizontalSlider->value());
    pthread->resumeThread();//播放繼續(xù) 設(shè)置為true
    //此處一定要先設(shè)置進(jìn)度條再開啟線程,否則線程開啟時(shí)再設(shè)置會沖突
}

void Widget::on_horizontalSlider_sliderMoved(int position)//進(jìn)度條拖動
{
    pthread->pauseThread();//播放暫停
}

void Widget::on_pushButton_pause_2_clicked()//結(jié)束播放
{
    pthread->stopThread();//結(jié)束線程
    qDebug()<<"結(jié)束播放,線程關(guān)閉";
    if(!pthread->isRunning())//線程不在運(yùn)行
    {
        if(this->isend!=true)//此時(shí)線程結(jié)束 已釋放,就不再釋放
        {
            //斷開連接
            disconnect(pthread,SIGNAL(sendFrame(int,Mat)),this,SLOT(receiveFrame(int,Mat)));//接收每一幀Mat
            delete pthread;
            qDebug()<<"釋放線程000000000000";
            //this->pthread = NULL;
            this->isend=true;//表明此時(shí)線程結(jié)束 已釋放
            //ui->pushButton_pause_2->setEnabled(false);
        }
    }
}

void Widget::on_pushButton_pause_3_clicked()//重新播放
{
    pthread->stopThread();//結(jié)束線程
    qDebug()<<"重新播放";
    if(!pthread->isRunning())//線程不在運(yùn)行
    {
        if(this->isend!=true)//此時(shí)線程結(jié)束 已釋放,就不再釋放
        {
            //斷開連接
            disconnect(pthread,SIGNAL(sendFrame(int,Mat)),this,SLOT(receiveFrame(int,Mat)));//接收每一幀Mat
            delete pthread;
            qDebug()<<"重播111111111111111";

        }

        //創(chuàng)建新線程
        pthread=new videothread("carMove.mp4");
        pthread->start();
        pthread->setIsrun(true);//視頻開始
        qDebug()<<"重播新創(chuàng)建線程333";
        connect(pthread,SIGNAL(sendFrame(int,Mat)),this,SLOT(receiveFrame(int,Mat)),Qt::BlockingQueuedConnection);//接收每一幀Mat

        this->isend=false;//表明此時(shí)線程還未結(jié)束
        //ui->pushButton_pause_2->setEnabled(true);
    }

}

?由于只是讀取幀,所以該播放器只能播放畫面,聲音暫時(shí)還沒做;

感謝觀看?。。?!

以上就是全部內(nèi)容,如果對您有幫助,歡迎點(diǎn)贊評論,或者發(fā)現(xiàn)有哪里寫錯(cuò)的,歡迎指正!

【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動

?

到了這里,關(guān)于【OpenCV+Qt】實(shí)現(xiàn)簡易視頻播放器——支持進(jìn)度條拖動的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Qt之基于QMediaPlayer的音視頻播放器(支持常見音視頻格式)

    Qt之基于QMediaPlayer的音視頻播放器(支持常見音視頻格式)

    Qt自帶了一個(gè)Media Player的例子,如下圖所示: 但是運(yùn)行這個(gè)例子機(jī)會發(fā)現(xiàn),連最基本的MP4格式視頻都播放不了。因?yàn)镼MediaPlayer是個(gè)殼(也可以叫框架),依賴本地解碼器,視頻這塊默認(rèn)基本上就播放個(gè)MP4,甚至連MP4都不能播放,如果要支持其他格式需要下載k-lite或者LAVFilter

    2024年02月02日
    瀏覽(31)
  • ChatGpt+人工修正 PyQt5 實(shí)現(xiàn)簡易視頻播放器

    支持功能: 1. 視頻播放速度調(diào)整 2. 視頻聲音調(diào)整 3. 視頻當(dāng)前播放幀截幀(用的ffmpeg 怎么裝自己百度去,截取準(zhǔn)確度很高,QT自帶的截幀那玩意信號不觸發(fā),不好使) 4. 視頻暫停

    2024年02月16日
    瀏覽(20)
  • QT實(shí)現(xiàn)視頻播放器

    QT實(shí)現(xiàn)視頻播放器

    1.我們需要的頭文件 2. .cpp文件 3.ui界面 ? ? ?

    2024年02月12日
    瀏覽(24)
  • qt實(shí)現(xiàn)簡單的視頻播放器
  • QT5.9實(shí)現(xiàn)一個(gè)視頻播放器播放 暫停進(jìn)度條

    QT5.9實(shí)現(xiàn)一個(gè)視頻播放器播放 暫停進(jìn)度條

    參考博主 1https://blog.csdn.net/liji_digital/article/details/83691035 參考博主2https://blog.csdn.net/qq_41071706/article/details/89855986 通過選擇按鈕選擇本地視頻文件 點(diǎn)擊播放按鈕播放文本框中的文件(不支持其他類型文件的異常檢測) 支持mp4 avi等等 如果不支持見參考博主2的內(nèi)容 點(diǎn)擊暫停按鈕

    2023年04月22日
    瀏覽(28)
  • C#制作簡易視頻播放器

    C#制作簡易視頻播放器

    1.打開vs2019新建一個(gè)窗體項(xiàng)目,選用框架.net framework4.7.2 2.在【工具箱】里隨便選中一個(gè)控件,右鍵單擊它 看到圖片中的【選擇項(xiàng)】了嘛,單擊它,打開添加組件的一個(gè)窗體 在添加組件窗體中的【COM組件】中找到【W(wǎng)indow Media Player】組件并勾選,然后【確定】 3.可以看到我們的

    2024年02月12日
    瀏覽(27)
  • linux系統(tǒng)中QT里面的視頻播放器的實(shí)現(xiàn)方法

    linux系統(tǒng)中QT里面的視頻播放器的實(shí)現(xiàn)方法

    ? ? ? 大家好,今天主要和大家聊一聊,如何使用QT中視頻播放器的方法。 ? 目錄 第一:視頻播放器基本簡介 第二:視頻播放器頭文件說明 ?第三:源文件的具體實(shí)現(xiàn)方法 第四:運(yùn)行效果顯示 ? ? ? ?與音樂播放器一樣使用 QMediaPlayer 類,不同的是需要使用 setVideoOutput(QVi

    2024年02月04日
    瀏覽(27)
  • 測試C#調(diào)用Aplayer播放視頻(3:編寫簡易播放器)

    測試C#調(diào)用Aplayer播放視頻(3:編寫簡易播放器)

    ??學(xué)習(xí)了參考文獻(xiàn)1中的示例代碼,也找出了前一篇文章中自己測試控件但無法播放視頻的問題(沒有將解碼庫文件復(fù)制到可執(zhí)行程序所在的codecs文件夾內(nèi)),本文基于APlayer組件編寫簡單的視頻播放器,主要實(shí)現(xiàn)以下功能: 序號 功能 說明 1 自定義logo 調(diào)用SetCustomLogo函數(shù)設(shè)

    2024年02月05日
    瀏覽(39)
  • 【Harmony OS】【ArkUI】ets開發(fā) 簡易視頻播放器

    前言:這一次我們來使用ets 的Swiper 組件、List 組件和Video 組件制作一個(gè)簡易的視頻播放器。本篇是以HarmonyOS 官網(wǎng)的codelab 簡易視頻播放器(eTS )為基礎(chǔ)進(jìn)行編寫。本篇最主要的內(nèi)容就是一個(gè)主界面包括頂部的視頻海報(bào)輪播,中部的視頻播放列表,以及點(diǎn)擊海報(bào)和播放列表進(jìn)

    2023年04月27日
    瀏覽(22)
  • 038-第三代軟件開發(fā)-簡易視頻播放器-自定義Slider (二)

    038-第三代軟件開發(fā)-簡易視頻播放器-自定義Slider (二)

    : Qt 、 Qml 、 3 、 4 、 5 歡迎來到我們的 QML C++ 項(xiàng)目!這個(gè)項(xiàng)目結(jié)合了 QML(Qt Meta-Object Language)和 C++ 的強(qiáng)大功能,旨在開發(fā)出色的用戶界面和高性能的后端邏輯。 在項(xiàng)目中,我們利用 QML 的聲明式語法和可視化設(shè)計(jì)能力創(chuàng)建出現(xiàn)代化的用戶界面。

    2024年02月07日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包