0

这是 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 表单在启动时打开,我猜是在主应用程序线程中。

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

我唯一能猜到的是,控制器线程失去了优先级,再也没有获得 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

4 回答 4

6

一个常见的混淆是QThread在它自己的单独线程中运行。不是这种情况; 相反,QThread在它控制的子线程中启动事件循环。QThread可以很容易地调用QThreadManager

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

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

于 2015-04-02T14:15:35.383 回答
3

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

但是,您似乎做错了

于 2013-02-06T13:51:45.617 回答
2

首先,QThread几乎不应该因为任何原因而被继承。

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

如果您只需要线程计算一些时间并在一段时间后执行某些操作,也许您可​​以QTimer改用并将QTimer::timeout()信号连接到您的插槽以显示经过的时间。

于 2013-02-06T09:38:54.270 回答
1

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

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

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

我认为不需要使用指针。把事情简单化。

如果这仍然不起作用,则说明您做错了其他事情,并且从您的代码中并不明显。

线程信号也不是使用sleep. 您应该查看信号量或条件变量等线程事件以用于线程信号发送。

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

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

于 2013-02-06T09:32:56.453 回答