如何通过在另一个线程中提出的升压信号更新QT GUI
How to update the Qt GUI from a Boost signal that is raised in another thread?
i具有一个普通的C 对象,该对象在单独的线程中运行数据采集例程,并带有名为acquisitionStageChangedEvent
的Boost信号,并带有以下签名:boost::signal2::signal<void(const std::string &)>
。我如何在新线程中启动收购并使用此信息更新UI,而无需跨线程例外?
在信号处理程序中将std::atomic<bool>
设置为true,并从QTimer
检查该标志。
这是一个工作示例,讲述了如何启动背景线程并在进度更新期间和任务结束时更新UI:
namespace Ui
{
class DtacqAcquisitionWidget;
}
class DtacqAcquisitionWidget : public QWidget
{
Q_OBJECT
public:
explicit AcquisitionWidget(QWidget *parent = 0);
~DtacqAcquisitionWidget();
private slots:
void on_pushButtonStart_clicked();
void onDtacqChangeState(const QString &stage);
/*... Other slots here */
private:
Ui::AcquisitionWidget *ui;
QFutureWatcher<void> *m_future_watcher; // This is to be able to run UI code at the end of the background thread
anlytcs::Dt100Acq m_dtacq; // The plain C++ object that raises the boost signal 'acquisitionStageChangedEvent'
};
在.cpp文件中:
DtacqAcquisitionWidget::DtacqAcquisitionWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::DtacqAcquisitionWidget)
{
ui->setupUi(this);
// Run the 'onAcquisitionFinished' slot at the end of the thread
m_future_watcher = new QFutureWatcher<void>(this);
connect(m_future_watcher, SIGNAL(finished()), this, SLOT(onAcquisitionFinished()));
// Acquisition stages update
m_dtacq.acquisitionStageChangedEvent.connect([this](const std::string &stage)
{
this->onDtacqChangeState(QString::fromStdString(stage));
});
}
void DtacqAcquisitionWidget::on_pushButtonStart_clicked() // Starting the acquisition
{
ui->pushButtonStop->setEnabled(true);
ui->pushButtonStart->setEnabled(false);
ui->progressBar->setValue(0);
// Start the acquisition in a new thread
QFuture<void> f = QtConcurrent::run(this, &DtacqAcquisitionWidget::acquireChannelData);
m_future_watcher->setFuture(f);
}
void DtacqAcquisitionWidget::onDtacqChangeState(const QString &stage)
{
if (thread() != QThread::currentThread())
{
QMetaObject::invokeMethod(this, "onDtacqChangeState",
Qt::BlockingQueuedConnection, Q_ARG(QString, stage));
}
else
{
ui->labelDtacqState->setText(stage);
ui->progressBar->setValue(ui->progressBar->value() + 40);
}
}
void DtacqAcquisitionWidget::onAcquisitionFinished()
{
// Set what to update here in the GUI here when the acquisition thread finishes
ui->labelDtacqState->setText("DONE!");
}
void DtacqAcquisitionWidget::acquireChannelData()
{
// This is running on a background thread (Non UI thread)
double time_sec = ui->spinBoxAcqTimeSec->value();
uint32_t channel_mask = getChannelMask();
std::string data_path = "C:/Users/pardinad/Desktop/DtacqData/";
m_dtacq.startAcquisition(time_sec, channel_mask, 250);
ui->labelDtacqState->setText("Acquisition Started!");
if(m_dtacq.completeAcquisition())
{
for (auto & dch : m_dtacq.dataChannels())
{
std::stringstream ss;
ss << data_path << std::setw(2) << std::setfill('0') << dch.channelNumber() << ".DAT";
std::string ch_file = ss.str();
dch.saveToFile(ch_file);
}
}
}
相关文章:
- 从C++本机插件更新Vector3数组
- Qt VTK交互风格的信号到小部件
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何在没有信号的情况下从C++执行QML插槽
- 线程之间的布尔停止信号
- cmake更新缓存的变量
- 更新到莫哈韦后出现cmath错误
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- OpenMP:并行更新数组总是需要减少数组吗
- 发出信号以从线程更新 UI
- 从主线程C++更新信号量
- 默认情况下,从工作线程发出Qt::信号会使主线程上的UI更新?
- 带有boost ::信号的自动更新依赖性类成员
- Qt 信号和插槽在更新 QTableView 时不起作用
- 如何通过在另一个线程中提出的升压信号更新QT GUI
- 从Boost signals2信号调用的函子的成员变量不更新
- C++/QML:ListView未根据来自QAbstractListModel的dataChanged信号进行更新
- 用信号和槽QT更新QLineEdit