通过QThread进行进度控制

2023-07-17  本文已影响0人  雯饰太一

说明:

线程类

class QSatelliteTrackThread : public QThread
{
    Q_OBJECT
public:

    enum ThreadRunState
    {
        TRS_Begin,
        TRS_Run,
        TRS_Pause,
        TRS_Stop
    };

    QSatelliteTrackThread();
    virtual ~QSatelliteTrackThread();

    void SetThreadRunState(ThreadRunState s);
signals:
void featureCreated(int fId,int t);//传入动目标id,类型 [0:星下点 1:卫星]
    void eventloopBreak();//打破时间循环,以继续或终止
public slots:
    void on_featureCreated(int fId, int t);
    void on_threadTimerWakeUp();        //执行处理逻辑
protected:
    virtual void run();
    bool ContinueCtrl();//进度控制

private:
    QTimer* m_pThreadTimer;
    ThreadRunState m_cState;
};

构造函数

QSatelliteTrackThread::QSatelliteTrackThread()
{
    m_cState = TRS_Begin;
    pThreadTimer = nullptr;
}

run函数

void QSatelliteTrackThread::run()
{
    m_pThreadTimer = new QTimer;
    m_pThreadTimer->setSingleShot(true);
    connect(m_pThreadTimer, &QTimer::timeout, this, &QSatelliteTrackThread::on_threadTimerWakeUp,Qt::DirectConnection); //保证子程创建工作
    connect(this, &QSatelliteTrackThread::featureCreated, this, &QSatelliteTrackThread::on_featureCreated, Qt::QueuedConnection);//保证主线程创建电磁特效
    m_pThreadTimer->start();
    exec();
    delete m_pThreadTimer;
    disconnect(this, &QSatelliteTrackThread::featureCreated, this, &QSatelliteTrackThread::on_featureCreated);
}

过程控制函数

#include <QEventLoop>
bool QSatelliteTrackThread::ContinueCtrl()
{
    switch (m_cState)
    {
    case QSatelliteTrackThread::TRS_Begin:
        return true;
        break;
    case QSatelliteTrackThread::TRS_Run:
        return true;
        break;
    case QSatelliteTrackThread::TRS_Pause:
    {
        QEventLoop loop;
        connect(this, &QSatelliteTrackThread::eventloopBreak, &loop, &QEventLoop::quit, Qt::QueuedConnection);
        loop.exec();
        return !(m_cState == TRS_Stop);
        break;
    }
    case QSatelliteTrackThread::TRS_Stop:
        return false;
        break;
    default:
        break;
    }
    return false;
}

具体做事情的函数

#include <QTimer>
void QSatelliteTrackThread::on_threadTimerWakeUp()
{
    m_cState = TRS_Run;

    for (qint64 t = m_dtStart; t < m_dtEnd; t += 1000)
    {
        for (int i = 0; i < m_vecSatellite.size(); i++)
        {
            if (!ContinueCtrl()) break;
            //... do something
            //Q_EMIT updateTrack(pSat);
            msleep(10);
        }
        if(!ContinueCtrl()) break;
    }
}

界面类

开始

void QSatelliteTreeWidget::on_pbPlay_clicked(bool checked)
{
    //调整状态
    setPushbuttonEnableState(ui.pbPlay, false);
    setPushbuttonEnableState(ui.pbPause, true);
    setPushbuttonEnableState(ui.pbStop, true);
    ui.pbPause->setText(QString::fromLocal8Bit("暂停"));

    if (m_pSatTrackThread == nullptr)
    {
        m_pSatTrackThread = new QSatelliteTrackThread();
    }
    m_pSatTrackThread->start();
}

暂停与继续

void QSatelliteTreeWidget::on_pbPause_clicked(bool checked)
{
    if (!m_pSatTrackThread) return;
    QString text = ui.pbPause->text();
    if (text.compare(QString::fromLocal8Bit("暂停")) == 0)
    {
        m_pSatTrackThread->SetThreadRunState(QSatelliteTrackThread::TRS_Pause);
        ui.pbPause->setText(QString::fromLocal8Bit("继续"));
    }
    else
    {
        m_pSatTrackThread->SetThreadRunState(QSatelliteTrackThread::TRS_Run);
        ui.pbPause->setText(QString::fromLocal8Bit("暂停"));
    }
}

结束

void QSatelliteTreeWidget::on_pbStop_clicked(bool checked /*= false*/)
{
    if (!m_pSatTrackThread) return;
    m_pSatTrackThread->SetThreadRunState(QSatelliteTrackThread::TRS_Stop);

    setPushbuttonEnableState(ui.pbPlay, true);
    setPushbuttonEnableState(ui.pbPause, false);
    setPushbuttonEnableState(ui.pbStop, false);
    ui.pbPause->setText(QString::fromLocal8Bit("暂停"));

    m_pSatTrackThread->quit();
    m_pSatTrackThread->wait();
    delete m_pSatTrackThread;
    m_pSatTrackThread = nullptr;
}

QRunnable + QObject应该也是可以满足条件的。但是这种方式都是在循环存在的时候成立,在没有循环的情况下,并不能立刻冻结或暂停一个线程。

期望的状态是,通过一个函数能够在任何时间,直接对线程自身的运行施以操控。

上一篇 下一篇

猜你喜欢

热点阅读