无法将BackgroundWorker进度百分比调整为任务的实际百分比

时间:2015-06-29 13:28:50

标签: c++ visual-c++ visual-studio-2013 backgroundworker

我写了一个程序,读取一个短视频,然后以减少的FPS写入几百帧。它工作得很好,但是" if"循环阻止了UI。我试图创建一个backgroudWorker来处理" if"循环,同时可以显示UI值,并且过程可以被"取消"按钮。 我的问题是:我不能制作"如果"循环遍历所有框架:

for (i = 0; i < frames_number; i++)

到最后一帧!它停在100,即使我尝试了多种解决方案来转换&#34; i&#34;百分比如:

progress = System::Convert::ToInt32((100*(i / frames_number)));

progress = (int)((float)i / (float)frames_number *100);

以下是代码的重要摘要:

private: System::Void CreateSlowMo_Click(System::Object^  sender, System::EventArgs^  e) {
        VideoCapture inputVideo(videoToOpenNameStr);
        if (!inputVideo.isOpened()) {
            MessageBox::Show(L"Error"); 
        }       
        fps =   int(inputVideo.get(CAP_PROP_FPS)); // get the frame rate of the video
        frames_number = int(inputVideo.get(CAP_PROP_FRAME_COUNT));     // get the total frames in the video
        this->progressBar1->Maximum = frames_number;      // Initilize the progress bar's maximum to the number of frames       
        outputVideo.open(name, CV_FOURCC('M', 'J', 'P', 'G'), fps_wanted, resolution, true);  // Create an output video 
        if (outputVideo.isOpened())
        {   
            this->backgroundWorker1->RunWorkerAsync(progress);     // Delegating the blocking operations to the background worker        
        }
        else {
            MessageBox::Show(L"Error creating the video");
            CreateSlowMo_button->Enabled = true;
        }       
    }

backgroundWorker1_DoWork:

private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {

    progress = (int)e->Argument; // get the intial value of the argument
    for (i = 0; i < frames_number; i++)
    {    
        inputVideo >> source; // read frame 

        if (backgroundWorker1->CancellationPending) {   // check if the User clicked on "Cancel"
            e->Cancel = true;
            break;    // Stop the convertion
        }
        if (source.empty()) { // we reached the last frame
            break;
            //  CreateSlowMo_button->Enabled = true;
        }    
        if (progress > 100) 
        { // verify we didn't exceed 100% of the task
            backgroundWorker1->ReportProgress(100);
            break;
        }       
        outputVideo << source; // write the frame to the output video
        progress = (int)(((float)i / (float)frames_number)* 100);
        backgroundWorker1->ReportProgress(progress);        
    }     
    this->backgroundWorker1->ReportProgress(100);
    e->Result = progress;    
}

backgroundWorker1_ProgressChanged:

private: System::Void backgroundWorker1_ProgressChanged(System::Object^  sender, System::ComponentModel::ProgressChangedEventArgs^  e) {
    this->progressBar1->Value = e->ProgressPercentage;
    toolStripStatusLabel1->Text = "Processing..." + progressBar1->Value.ToString() + "%";
    richTextBox6->Text = e->ProgressPercentage.ToString();  
}

backgroundWorker1_RunWorkerCompleted:

private: System::Void backgroundWorker1_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e) {
     // in case the background process is finished with a cancel
    if (e->Cancelled) 
    {
        toolStripStatusLabel1->Text = "Task Cancelled";
    }
    // check if an error occurred in the backgroud process
    else if (e->Error != nullptr)
    { 
        toolStripStatusLabel1->Text = "Error while creating the SlowMo";
    }
    else 
    {   // task completed normally
        this->toolStripStatusLabel1->Text = "SlowMo Created successfully!";
        this->cancel_button->Enabled = false;
        MessageBox::Show(L"Finished creating the sloMo");
        this->toolStripStatusLabel1->Text = "Done";
        this->CreateSlowMo_button->Enabled = true;   
        this->richTextBox5->Text = "value " + e->Result;
    }
}

以下是来自resulats的一些截图(我添加了文本框以显示&#39; i&#39;,&#39;进展&#39;和e-&gt;结果)&#39; i&# 39;和&#39;进步&#39;是int = 0,在文件&#39; variables.h&#39;

中定义
extern int i ;
extern int progress;

和&#39; variables.cpp&#39;:

int i = 0;
int progress =0;

UI when backgroundWorker done

UI when backgroundWorker done

1 个答案:

答案 0 :(得分:0)

您检查过frames_number的值吗?或者,如果if循环中的任何for语句在执行期间的任何时间变为真,那么

我怀疑frames_numberfor循环之前得到的值不正确,或source.empty()变为真。