• 2278阅读
  • 5回复

[讨论]Qt多线程异步处理进度条 [复制链接]

上一主题 下一主题
离线lwei24
 

只看楼主 倒序阅读 楼主  发表于: 2021-05-17
各位大佬,目前在QTableWidget上使用多线程异步处理多个进度条,每个进度条都有自己的进度,并且互不影响,要怎么做才能实现呢?
在线clickto

只看该作者 1楼 发表于: 2021-05-17
通过信号,每个进度条接受自己的工作线程的进度
离线lwei24

只看该作者 2楼 发表于: 2021-05-20
回 clickto 的帖子
clickto:通过信号,每个进度条接受自己的工作线程的进度 (2021-05-17 15:08) 

目前我就是用多线程,每个线程有自己的进度条,并每个进度条有自己的进度,但是由于要插入到表格QTableWidget中,但是有个问题,就是每次插入QTableWidget,由于线程有多个,可能会插入多个进度条,存在进度条之间重复利用,即错位的情况,比如说,第三个的进度条没有显示,跑到第二个进度条里显示了。。。
在线clickto

只看该作者 3楼 发表于: 2021-05-20
回 lwei24 的帖子
lwei24:
目前我就是用多线程,每个线程有自己的进度条,并每个进度条有自己的进度,但是由于要插入到表格QTableWidget中,但是有个问题,就是每次插入QTableWidget,由于线程有多个,可能会插入多个进度条,存在进度条之间重复利用,即错位的情况,比如说,第三个的进度条没有显示,跑到第二个进度条里显示了。。。


???不太明白你的意思。应该是每个进度条有确定的线程进来行计算值。
我这里给写了一个简单的例子,只产生3个单元格,每个单元格一个线程,不断的变化进度条的值,并不会出现你说的情况,可以看看。
要说明的是,由于使用时间做种子,导致随机数并不那么随机,所以我人为的做了些区别,但这并不影响其实质,3个进度条由3个线程产生值。
呃,,还是无法上传附件,我放这里了:http://91io.cn/s/893qXsw
离线lwei24

只看该作者 4楼 发表于: 2021-05-21
回 clickto 的帖子
clickto:
???不太明白你的意思。应该是每个进度条有确定的线程进来行计算值。
我这里给写了一个简单的例子,只产生3个单元格,每个单元格一个线程,不断的变化进度条的值,并不会出现你说的情况,可以看看。
要说明的是,由于使用时间做种子,导致随机数并不那么随机,所以我人为的做了些区别,但这并不影响其实质,3个进度条由3个线程产生值。
呃,,还是无法上传附件,我放这里了:http://91io.cn/s/893qXsw  

大佬,刚刚看了你写的,的确可以多线程中一个线程控制一个进度条。
我的代码主要代码如下:


class myWidget : public QWidget
{
Q_OBJECT
public:
myWidget(QWidget *parent = nullptr);
~myWidget();
private:
    QLineEdit *m_lineEdit;
    eCustomTableWidget *m_eTableWidget;
    int m_threadCount;
signals:
    void sigStartTask(int num);
};


myWidget::myWidget(QWidget *parent)
    : myWidget(QWidget)
{
    m_lineEdit = new QLineEdit(this);
    m_lineEdit->resize(40,40);
    m_lineEdit->move(this->width()*20/100, this->height()*20/100);
    m_threadCount = QString(m_lineEdit->text()).toUInt();
    
    m_eTableWidget = new eCustomTableWidget(this);
    m_eTableWidget->resize(this->width()*85/100, this->height()*65/100);
    m_eTableWidget->move(this->width()*20/100, this->height()*25/100);
    
}

myWidget::~myWidget()
{

}

void myWidget::clickedBtn1()
{
    
    connect(this, &clickedBtn1::sigStartTask, m_eTableWidget, &eCustomTableWidget::startTask);    
    emit sigStartTask(m_threadCount);
}

class eCustomTableWidget : public QTableWidget
{
Q_OBJECT
public:
    eCustomTableWidget(QWidget *parent = nullptr);
    ~eCustomTableWidget();
public slots:
    void startTask(int num);
    
private:
    QVector<QTableWidgetItem *> m_vItem0;
    QVector<QProgressBar *> m_vProgressBar;
    QVector<QThread*> m_vThread;
    QVector<Worker*> m_vWorker;    //继承QObject,处理线程
};

void eCustomTableWidget::startTask(int num)
{
    m_vItem0.resize(num);
    m_vProgressBar.resize(num);
    m_vThread.resize(num);
    m_vWorker.resize(num);
    for(int i = 0; i < num; i++)
    {
        m_vItem0 = new QTableWidgetItem();
        m_vItem0->setText(QString("the progressBar%1").arg(i+1));
        
                m_vProgressBar = new QProgressBar(this);
        m_vProgressBar->setStyleSheet("QProgressBar{border:2px solid grey;border-radius:5px;text-align:center;color:white;}"
                                         "QProgressBar::chunk{background-color:#003DA6;width:20px;}");
        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, &eCustomTableWidget::slotWorkerNullptr);
            connect(m_vWorker, &Worker::sigWorkerResult, this, &eCustomTableWidget::slotWorkerResult);
            connect(m_vWorker, &Worker::sigUpdateProgressValue, this, &eCustomTableWidget::slotUpdateProgressValue);
            connect(this, &eCustomTableWidget::sigStartWork, m_vWorker, &Worker::startWork);

            m_vThread->start();
        }
        
        
        int rowIndex = rowCount();
        insertRow(rowIndex);
        setItem(rowIndex, 0, m_vItem0);
        
        QWidget *pWidget = new QWidget();
        pWidget->setAttribute(Qt::WA_TranslucentBackground);
        pWidget->setWindowFlags(Qt::FramelessWindowHint);
        QHBoxLayout *pHBoxLayout = new QHBoxLayout;
        pHBoxLayout->addWidget(m_vProgressBar);
        pHBoxLayout->setMargin(15);
        pWidget->setLayout(pHBoxLayout);
        setCellWidget(rowIndex, 1, pWidget);
                
        emit sigStartWork();
    }
}


j我的不知道为什么,有两个场景:场景1.第一次启动一个线程A,线程A执行结束后,A对应的进度条也会插入QTableWidget上。第二次启动线程B,线程B的进度条会插入到第二行,但它的进度条的值却显示在A对应的进度条上。场景2:一次性启动多个线程,就会插入多个进度条,假设ABC三个线程,ABC三个线程都会插入QTableWidget,当A进度达到100,B进度却没有显示,直接跳到A对应的进度跳上显示了,出现这种进度条的值错位。
目前还在找原因,想把这两个场景都做出来。。。




离线deepgui

只看该作者 5楼 发表于: 2021-05-23
使用mutex保证一个线程改变table, 更新后允许下一个线程做改变
快速回复
限100 字节
 
上一个 下一个