C++ 尝试启动新线程时,某些设置不正确

C++ 尝试启动新线程时,某些设置不正确,c++,multithreading,qt,C++,Multithreading,Qt,我正在尝试创建一个“响应gui”,这基本上意味着我有一个应用程序,在主窗口上有一个按钮。在我按下这个按钮后,我想显示“进度条窗口”,它将显示正在完成的工作的进度,当然这项工作是在单独的线程中完成的 不幸的是,我在这个进度条窗口的ctor中启动一个新线程的方法似乎不起作用,我的gui被冻结了。 这是指向此项目的链接,因此您可以下载并运行它,而无需复制和粘贴任何内容: 谁能告诉我我做错了什么以及如何修复它 编辑 progress_dialog::progress_dialog(QWidget *pa

我正在尝试创建一个“响应gui”,这基本上意味着我有一个应用程序,在主窗口上有一个按钮。在我按下这个按钮后,我想显示“进度条窗口”,它将显示正在完成的工作的进度,当然这项工作是在单独的线程中完成的

不幸的是,我在这个进度条窗口的ctor中启动一个新线程的方法似乎不起作用,我的gui被冻结了。 这是指向此项目的链接,因此您可以下载并运行它,而无需复制和粘贴任何内容:

谁能告诉我我做错了什么以及如何修复它

编辑

progress_dialog::progress_dialog(QWidget *parent) :
    QDialog(parent)
{/*this is this progress dialog which is displayed from main window*/
    setupUi(this);
    working_thread_ = new Threaded;
    connect(working_thread_,SIGNAL(counter_value(int)),progressBar,SLOT(setValue(int)),Qt::QueuedConnection);
    working_thread_->start();//HERE I'M STARTING THIS THREAD
}  

/*this is run fnc from the threaded class*/
void Threaded::run()
{
    unsigned counter = 0;
    while(true)
    {
        emit counter_value(counter);
        counter = counter + 1 % 1000000;
    }
}

您是否尝试使用父对象启动线程?

您是否尝试使用父对象启动线程?

与紧循环不好这一事实无关,您应该限制对主GUI线程进行更改的速率:来自线程的信号在主线程事件循环中发出后立即排队,由于GUI无法快速更新,重绘事件会排队而不是实时执行,这会冻结GUI

无论如何,更新GUI的速度比屏幕刷新速度快是没有用的

您可以尝试以下方法:

void Threaded::run()
{
    QTime time;
    time.start();   
    unsigned counter = 0;
    // initial update
    emit counter_value(counter);

    while(true)
    {
        counter = (counter + 1) % 1000000;

        // 17 ms => ~ 60 fps
        if(time.elapsed() > 17) {            
            emit counter_value(counter);            
            time.restart();            
        }
    }
}

与紧循环不好这一事实无关,您应该限制对主GUI线程进行更改的速率:来自线程的信号在主线程事件循环中发出后立即排队,并且由于GUI无法快速更新,因此重绘事件排队,而不是实时执行,这会冻结GUI

无论如何,更新GUI的速度比屏幕刷新速度快是没有用的

您可以尝试以下方法:

void Threaded::run()
{
    QTime time;
    time.start();   
    unsigned counter = 0;
    // initial update
    emit counter_value(counter);

    while(true)
    {
        counter = (counter + 1) % 1000000;

        // 17 ms => ~ 60 fps
        if(time.elapsed() > 17) {            
            emit counter_value(counter);            
            time.restart();            
        }
    }
}


如果您深入了解更多细节,尝试将问题锁定到代码的特定部分,并将该部分发布在此处,这将是一个好主意。你不会发现有人想阅读整个项目来找出问题所在。@Shahbaz这个项目只是一个框架,所以一切都很简单,我解释的应该足够了,但我也在这里发布了代码。不相关,但类名应该是CamelCase。@StefanoBorini以及为什么类名应该是CamelCase?哪条规则是这么说的?@smallB:命名约定,从Java和Qt继承而来。不是STL和boost,我同意。由于您使用的是Qt,因此保留该命名是有意义的。如果您深入了解更多细节,尝试将问题定位到代码的特定部分,并将该部分发布在此处,这将是一个好主意。你不会发现有人想阅读整个项目来找出问题所在。@Shahbaz这个项目只是一个框架,所以一切都很简单,我解释的应该足够了,但我也在这里发布了代码。不相关,但类名应该是CamelCase。@StefanoBorini以及为什么类名应该是CamelCase?哪条规则是这么说的?@smallB:命名约定,从Java和Qt继承而来。不是STL和boost,我同意。因为您使用的是Qt,所以将该命名保留在父对象中还是在父对象中是有意义的?如果前者是否定的,后者是肯定的。@riv333,答案不是写问题的地方。这就是评论的目的。我知道你的声誉不允许发表评论,但你可以回答几个简单的问题,只是为了让你的声誉足够高。@Shahbaz抱歉,我是新来的,我想发表评论,但不知道怎么做。现在我明白我的声誉太低了。@smallB是的,我的意思是在父对象中。只是一个想法。是在父对象中还是在父对象中?如果前者是否定的,后者是肯定的。@riv333,答案不是写问题的地方。这就是评论的目的。我知道你的声誉不允许发表评论,但你可以回答几个简单的问题,只是为了让你的声誉足够高。@Shahbaz抱歉,我是新来的,我想发表评论,但不知道怎么做。现在我明白我的声誉太低了。@smallB是的,我的意思是在父对象中。这只是一个想法。