Qt线程和循环问题

时间:2013-02-06 09:25:19

标签: c++ multithreading qt qthread

这是QThread子类的run方法:

void crono::Controller::run() {

    //initialise timer
    int *i = & this->model->seconds_elapsed;

    for (*i = 0; *i < this->model->seconds_total; (*i)++) {

    //calculate current seconds/minutes/hours elapsed starting  from seconds_elapsed (*i)
    this->model->tick(); 

    //should display in the form the time elapsed
    this->vista->showTime(); 
    sleep(1000);


    }

    Beep(1000, 500); //beep when all is over

}

控制器更新模型值。

QT表单在启动时打开,我猜在主应用程序线程中。

问题是对debug * i = 0和seconds_total = X&gt;的鄙视0,循环只执行一次,在第一次调试停止后(它没有结束),表格弹出但没有任何反应。

我唯一可以猜到的是,Controller Thread失去了优先级,再也没有获得cpu。

如何避免这种情况?

修改 的 我正在尝试使用QTimer,运气不好。

我将更新声明为公共插槽,然后实现如下:

void crono::Controller::update() { 

    this->modello->tick();
    this->vista->showTime();

    //eventually stop at some point (pointer to timer and timer->stop()? 
    //...
    //Beep(1000, 500);
}  

我将QTimer插入控制器(线程)对象而不是循环周期:

void crono::Controller::run() {

    //inizializzo timer
    int *i = & this->modello->secondi_trascorsi;

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()),this, SLOT(update()));
    timer->start(1000);


}

我不知道为什么,但是从不调用update()方法,而是被无限次调用。为什么呢?

4 个答案:

答案 0 :(得分:5)

常见的混淆是QThread在自己独立的线程中运行。不是这种情况;相反,QThread在它控制的子线程中启动一个事件循环。可以轻松地将QThread称为QThreadManager

简而言之,不要继承QThread,因为您创建的功能驻留在主线程中(而不是QThread处理的线程)。创建一个QObject子类,其中一个插槽连接到started()信号。然后使用moveToThread()并在run()个实例上调用QThread

此外,您无法直接从子线程调用主线程函数。您需要一个排队的连接信号到主线程中的对象以显示对话框。

答案 1 :(得分:3)

正如Tim Meyer在他的评论中指出的那样,你需要在QThread:exec()实现结束时调用QThread::run(),这是为了启动线程的事件循环,这是为了工作的信号/插槽机制。

然而,它似乎是you're doing it wrong

答案 2 :(得分:2)

首先,QThread几乎不应该被遗传。

线程通常会像在那里描述的那样完成:http://qt-project.org/doc/qt-4.8/QThread.html#details

如果您只是需要线程计算一段时间并在一段时间后执行操作,可能您可以使用QTimer代替并将QTimer::timeout()信号连接到您的插槽以显示已用时间。

答案 3 :(得分:1)

我确定你的循环应该是这样的:

//initialize timer
int elapsed = this->model->seconds_elapsed;

for (int i = 0; i < elapsed; i++) 

我认为没有必要使用指针。保持简单。

如果这仍然不起作用,那么你做错了其他事情,而且你的代码并不明显。

此外,使用sleep未完成线程信令。您应该查看线程事件,如信号量或条件变量,以用于线程信号。

如果您想定期更新值,为什么不使用QTimer?

sleep只有非常少的有效用途,我确信你正在解决一个不需要睡眠的问题。