我遇到这种情况:我需要不断更新某些UI标签,其中包含我从某些SPI传感器读取的值,而不会阻止UI。每个传感器的代码几乎相同,如下所示:
double SPIHandler::scaleGetQuickWeight(){
double weightValue = SCALE_ERROR_VALUE;
QElapsedTimer *timer = new QElapsedTimer();
timer->start();
QFuture<double> future = QtConcurrent::run(&SPIHandler::thread_scaleGetWeight);
while(timer->elapsed() < 5000){
if (future.isFinished()){
future.end();
weightValue = future.result();
return weightValue;
}
}
//when called by the functions I posted below, the program always ends here
future.cancel();
myParent->log("Malfunctioning scale", MainWindow::LOG_ERROR);
return SCALE_ERROR_VALUE;
}
double SPIHandler::thread_scaleGetWeight(){
float val;
//myParent->log("check");
if (scale_read_value(fd_scale, &val) == 0){
return ftod(convertReadingsIntoWeight(val, k_cal, q_cal)*1000);
} else {
myParent->log("Malfunctioning scale in QtConcurrent", MainWindow::LOG_ERROR);
return SCALE_ERROR_VALUE;
}
}
对于每个传感器,我有一个由QtConcurrent :: run()调用启动的线程,如果在5秒后它没有给出结果,我会停止:代码的这些部分在其他地方使用时效果很好。 当我尝试从另一个线程调用包含QtConcurrent :: run()调用的函数时出现问题,而该调用又是由QTimer超时启动的另一个QtConcurrent :: run()创建的。 QWidget中需要更新标签的相关代码是:
DiagnosticWindow::DiagnosticWindow(QWidget *parent) :
QTabWidget(parent),
ui(new Ui::DiagnosticWindow)
{
[...]
//connect to make sure that timer is running only when the right tab is selected
connect(this, SIGNAL(currentChanged(int)), this, SLOT(on_diagnosticWindow_currentChanged(int)));
//setting up timer
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(on_timer_timeout()));
///setting up QFutureWatcher
watcher = new QFutureWatcher<void>();
connect(watcher, SIGNAL(finished()), this, SLOT(updateGraphics()));
[...]
}
void DiagnosticWindow::on_diagnosticWindow_currentChanged(int index)
{
//slot to start timer when tab 2 is selected
if (index == 2){
[...]
timer->setSingleShot(false);
timer->start(750);
} else{
printf("timer stopped\r\n");
timer->stop();
[...]
}
}
void DiagnosticWindow::on_timer_timeout(){
//slot to start QtConcurrent on timer timeout
QFuture<void> future = QtConcurrent::run(&diagnosticWindow::updateValues);
watcher->setFuture(future);
}
void DiagnosticWindow::updateValues(){
//function run by QFuture: I didn't post the code of these functions,
//but each one simply calls the respective function written like the one
//posted above
weight = myParent->deviceScaleGetQuickWeight();
temperature = myParent->devicePressGetValue();
pressure = myParent->deviceTempGetValue();
}
void DiagnosticWindow::updateGraphics(){
//slot called when QFutureWatcher signals isFinished()
ui->lbl_peso->setText(QString("%1").arg(weight));
ui->lbl_pressione->setText(QString("%1").arg(pressure));
ui->lbl_temperatura->setText(QString("%1").arg(temperature));
}
总而言之,这应该是行为:
选择标签 - &gt;计时器开始 - &gt;计时器停止 - &gt; QFuture 1开始 然后调用另一个QFuture 2 - &gt; QFuture 2结束 - &gt; QFuture 1 结束 - &gt;用户界面更新
它确实以这种方式工作,但它总是给我带来故障错误。 QFuture 1正在工作,因为在5秒后,我收到了故障错误,所以在我看来,QFuture 2从不调用该功能。我尝试添加评论&#34; myParent-&gt;日志(&#34; check&#34;);&#34;到QFuture 2调用的函数有证明该函数被调用,但在这种情况下我从来没有得到那条日志消息(但是当我从代码的其他部分读取传感器时我得到它)。
问题是:上面代码中的某些内容可以解释这种行为吗?有什么我想念的吗?如果需要,我可以添加更多代码,但由于我可以正确读取传感器值,即使是来自同一个DiagnosticWindow类,我也不认为它可以提供帮助。 谢谢你们