如何在线程中更新qcustomplot数据
How to update QCustomPlot Data in thread?
我想在c 中显示qcustomplot的实时数据whit帮助。所以我这样做:
在标题文件中:
class QtGuiApplication : public QMainWindow
{
Q_OBJECT
public:
QtGuiApplication(QWidget *parent = Q_NULLPTR);
private:
Ui::QtGuiApplicationClass ui;
//plot
QCustomPlot* plot_;
std::thread thread_Displayer_;
bool thread_run_flag_ = false;
void thread_Displayer_fn();
};
和在源文件中,我使用按钮来启动线程,然后...像这样:
void QtGuiApplication::btn_Display_clicked()
{
if (thread_run_flag_)
{
ui.btn_Dispaly->setText("Display");
thread_run_flag_ = false;
if (thread_Displayer_.joinable())
{
thread_Displayer_.join();
}
}
else
{
thread_run_flag_ = false;
if (thread_Displayer_.joinable())
{
thread_Displayer_.join();
}
ui.btn_Dispaly->setText("Stop");
thread_run_flag_ = true;
thread_Displayer_ = std::thread(&QtGuiApplication::thread_Displayer_fn,
this);
}
}
void QtGuiApplication::thread_Displayer_fn()
{
double y_max_ = 0;
double y_min_ = 0;
while (thread_run_flag_)
{
QVector<double> x(16384), y(16384);
for (int i = 0; i<16384; ++i)
{
x[i] = i;
y[i] = x[i];
if (y[i] > y_max_)
y_max_ = y[i];
if (y[i] < y_min_)
y_min_ = y[i];
}
plot_->yAxis->setRange(y_min_, y_max_);
plot_->graph(0)->setData(x, y);
plot_->replot();
}
}
,但是当我启动代码时会发生此错误:
"不能将事件发送给另一线程拥有的对象"
我该如何解决?
您需要(或至少这是对我有效的方式(创建一个信号,该信号将发出线程中的每一个for循环的迭代。然后,将此信号连接到将进行数据实际更新
的插槽class QtGuiApplication : public QWidget
{
Q_OBJECT
public:
explicit QtGuiApplication(QWidget *parent = 0);
~QtGuiApplication();
private slots:
void setPlotData(QVector<double> x,QVector<double> y);
void pushButtonClicked();
signals:
void newData(QVector<double> x, QVector<double> y);
private:
Ui::QtGuiApplication *ui;
QCustomPlot* plot_;
std::thread thread_Displayer_;
bool thread_run_flag_ = false;
void thread_Displayer_fn();
};
double fRand(double fMin, double fMax){
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
QtGuiApplication::QtGuiApplication(QWidget *parent) :
QWidget(parent),
ui(new Ui::QtGuiApplication)
{
// Set up UI
ui->setupUi(this);
plot_ = ui->qcustomplot;
// Register data type for signals
qRegisterMetaType<QVector<double>>("QVector<double>");
// Prepare graph
plot_->addGraph();
// Connect
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(pushButtonClicked()));
connect(this,SIGNAL(newData(QVector<double>,QVector<double>)),this,SLOT(setPlotData(QVector<double>,QVector<double>)));
}
QtGuiApplication::~QtGuiApplication()
{
delete ui;
}
void QtGuiApplication::pushButtonClicked()
{
if (thread_run_flag_)
{
ui->pushButton->setText("Display");
thread_run_flag_ = false;
if (thread_Displayer_.joinable())
{
thread_Displayer_.join();
}
}
else
{
thread_run_flag_ = false;
if (thread_Displayer_.joinable())
{
thread_Displayer_.join();
}
ui->pushButton->setText("Stop");
thread_run_flag_ = true;
thread_Displayer_ = std::thread(&QtGuiApplication::thread_Displayer_fn,
this);
}
}
void QtGuiApplication::setPlotData(QVector<double> x, QVector<double> y)
{
plot_->graph(0)->setData(x, y);
plot_->rescaleAxes();
plot_->replot();
}
void QtGuiApplication::thread_Displayer_fn()
{
while (thread_run_flag_)
{
QVector<double> x(ui->spinBox->value()), y(ui->spinBox->value());
for (int i = 0; i<ui->spinBox->value(); ++i)
{
x[i] = i;
y[i] = fRand(0,10);
}
emit newData(x,y);
usleep(ui->doubleSpinBox->value()*1000);// convert to us
}
}
请注意,我还在EMMIT之后添加了usleep
功能。如果您不放弃它,您将无法再次按下按钮并停止,我认为这是因为发送数据的速率。
在这里您可以找到整个示例。
使此功能静态并尝试void QtGuiApplication::thread_Displayer_fn()
static void QtGuiApplication::thread_Displayer_fn()
因为从类QtGuiaPplication创建的对象已经由主线程拥有,并且您正在尝试使用上述语句从另一个线程(子线程(调用它的方法。
相关文章:
- 从C++本机插件更新Vector3数组
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- cmake更新缓存的变量
- 更新到莫哈韦后出现cmath错误
- OpenMP:并行更新数组总是需要减少数组吗
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 指针没有更新它在void函数内部指向的值
- 如何在c++中获取要更新的值
- 已修改的LinkedList未在文本文件本身中更新
- Qt:当QListView获得新条目时,如何更新QStringList
- 更新的矢量元素不打印
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 如何在ECS框架中更新组件数据和通知系统
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 如果我想在没有更新编译器的情况下使用新功能,该怎么办?
- 如何在 C++11 中查找和更新向量中的一个嵌套结构
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 在 emscripten 网页汇编正在运行期间更新进度条?
- 如何在线程中更新qcustomplot数据
- QCustomPlot/Widget不显示图形/更新