查看完整版本: [-- 关于多线程处理多个进度插入QTableWidget的疑问 --]

QTCN开发网 -> Qt基础编程 -> 关于多线程处理多个进度插入QTableWidget的疑问 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

lwei24 2021-08-09 14:39

关于多线程处理多个进度插入QTableWidget的疑问

各位大佬,请大家指点一下:如下代码,在Qt平台下,多线程通过数组的方式创建,每个多线程都有自己的工作线程,每个工作线程都有一个对应的进度条,以上代码中出现的问题是多个进度条值可能会错乱,例如
当有两个进度条时,进度条1可能从1%递增到100%后再降到1%,最后再递增到100%(或者递增过程中出现失败),进度条2从1%递增到100%,正常显示。
为什么每个工作线程对应一个进度条,某个进度条的值还是会递增两次或多次呢?后来,我检查了代码,在每次处理进度条达到100%后,退出该线程,结果,还是会接受到工作线程的信号,导致进度条重新从1%计算开始。是不是由于每个工作线程的信号都是一样的影响了呢?有什么办法解决这个问题吗?或者有什么更好的办法实现多线程处理多个进度条值而不会错乱吗?欢迎各位大佬赐教,小弟不胜感激!!!!
/*****************************/
//Worker类
class Worker : public QObject
{
    Q_OBJECT
public:
    Worker(QTableWidgetItem *pItem0, QProgressBar *pProgressBar);


public slots:
    void slotStartWork();

signals:
    void sigProgressValue(QProgressBar *pProgressBar, int nCode);
    void sigStartWork();

private:
    QTableWidgetItem *m_item0;
    QProgressBar *m_progressBar;
};

Worker::Worker(QTableWidgetItem *pItem0, QProgressBar *pProgressBar)
{
    m_item0 = pItem0;
    m_progressBar = pProgressBar;
}

void Worker::slotStartWork()
{
    //dosomething
    if(true)
    {
        emit sigProgressValue(m_progressBar, i)//成功,返回进度条值,从1递增100.
    }
    else
    {
        emit sigProgressValue(m_progressBar, -1);//失败
    }
        
}
/*****************************/

//CustomTableWidget类
class CustomTableWidget : public QTableWidget
{
    QOBJECT
public:
    CustomTableWidget(QWidget *parent = nullptr);
    ~CustomTableWidget();
    
public slots:
    void slotProgressValue(QProgressBar *pProgressBar, int nCode);
    void slotWorkerNullptr();
    
signals:
    void sigStartWork();
    
private:
    QVector<QTableWidgetItem *> m_vItem0;
    QVector<QProgressBar *> m_vProgressBar;
    QVector<Worker *> m_vWorker;
    QVector<QThread *>m_vThread;
}

CustomTableWidget::CustomTableWidget(QWidget *parent)
    :QTableWidget(parent)
{
}

CustomTableWidget::~CustomTableWidget()
{
    for(int i = 0; i < m_vThread.size(); i++)
    {
        if(m_vThread != NULL)
        {
            if(m_vWorker != NULL)
            {
                m_vWorker->stop();
            }

            if(m_vThread->isRunning())
            {
                m_vThread->quit();
                m_vThread->wait();
            }
        }
    }
}

void CustomTableWidget::startCalcProgressBar()
{
    m_vItem0.resize(threadCount);
    m_vItem0.resize(threadCount);
    m_vWorker.resize(threadCount);
    m_vThread.resize(threadCount);
    for(int i = 0; i < threadCount; i++)
    {
        m_vItem0 = new QTableWidgetItem();
        m_vItem0->setText(QStringLiteral("进度条%1").arg(i));
        m_vItem0->setTextAlignment(Qt::AlignCenter);
        
        m_vProgressBar = new QProgressBar(this);
        m_vProgressBar->setStyleSheet("QProgressBar{border:none;border-radius:5px;text-align:center;color:white;}"
                                     "QProgressBar::chunk{background-color:#003DA6;width:20px;}");
        m_vProgressBar->setFont(m_font);
        m_vProgressBar->setMinimum(0);
        m_vProgressBar->setMaximum(100);
        m_vProgressBar->setAlignment(Qt::AlignCenter);
        m_vProgressBar->setValue(0);    
        
        if(m_vWorker == NULL)
        {
            m_vThread = new QThread(this);
            m_vWorker = new Worker(m_vItem0, m_vProgressBar);
            m_vWorker->moveToThread(m_vThread);
            connect(m_vThread, &QThread::finished, m_vWorker, &Worker::deleteLater);
            connect(m_vThread, &QThread::finished, this, &CustomTableWidget::slotWorkerNullptr);
            connect(m_vWorker, &Worker::sigProgressValue, this, &CustomTableWidget::slotProgressValue);
            connect(this, &CustomTableWidget::sigStartWork, m_vEncryptWorker, &encryptWorker::slotStartWork);
            m_vThread->start();
        }
        emit sigStartWork();
        
    }
}

void CustomTableWidget::slotWorkerNullptr()
{
    for(int i = 0; i < m_vWorker.size(); i++)
    {
        if(m_vWorker != NULL)
        {
            m_vWorker = NULL;
        }
    }
}

void CustomTableWidget::slotProgressValue(QProgressBar *pProgressBar, int nCode)
{
    if(nCode < 0)
    {
        //显示失败
        pProgressBar->setValue(0);
        for(int i = 0; i < m_vThread.size(); i++)
        {
            if(m_vThread->isRunning())
            {
                m_vThread->exit(nCode);
            }
        }
    }
    pProgressBar->setValue(nCode);
    if(nCode == 100)
    {
        //显示成功
        pProgressBar->setValue(100);
        
        //位置1
        /*
        for(int i = 0; i < m_vThread.size(); i++)
        {
            if(m_vThread->isRunning())
            {
                m_vThread->exit(0);
            }
        }
        */
    }    
}


查看完整版本: [-- 关于多线程处理多个进度插入QTableWidget的疑问 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled