从GUI线程发送参数到工作线程。

时间:2021-05-23 21:03:32

I have got some problem in Qt. I assign some parameters in GUI thread:

我在Qt有一些问题,我在GUI线程中分配了一些参数:

newton.h (work thread) :

牛顿。h(工作线程):

class Newton : public QThread

resic.cpp (GUI thread) :

resic。cpp(GUI线程):

.
.
.
 Newton mythread;

resic::resic(QWidget *parent) :
  QWidget(parent),
  ui(new Ui::resic)
{
    ui->setupUi(this);
    mythread.start();

}

void resic::on_PushButton_clicked()
{
   w1=ui->doubleSpinBox_2->value();
   um1=ui->doubleSpinBox->value();
   alpha1=ui->doubleSpinBox_3->value();
   et01=ui->doubleSpinBox_4->value();
   Er1=ui->doubleSpinBox_11->value();
   Rx1=ui->doubleSpinBox_12->value();
   xa1=ui->doubleSpinBox_8->value();
   xb1=ui->doubleSpinBox_9->value();
   q1=ui->doubleSpinBox_10->value();
   ya1=(q1-2*q1);
   yb1=ui->doubleSpinBox_10->value();
   maxl1=ui->spinBox->value();
}

And I want to send these parameters after click on the button to the work thread and then run some calculation in this work thread. But I don't know how send parameters. Can you give me some advice, please?

我想在点击工作线程的按钮后发送这些参数,然后在这个工作线程中运行一些计算。但我不知道如何发送参数。你能给我一些建议吗?

Thank you very much.

非常感谢。

2 个解决方案

#1


2  

A simple solution to running a piece of code in a worker thread is to leverage Qt Concurrent framework. Another solution is to put the worker into a QObject, and use a QThread directly.

在工作线程中运行一段代码的简单解决方案是利用Qt并发框架。另一种解决方案是将worker放入一个QObject中,并直接使用QThread。

struct Parameters {
  double w1, um1, alpha1, et01, ...;
};

struct Result {
  ...
};

Result calculate(const Parameters & p) {
  ...
}

class resic : public QWidget {
  ...
  QFutureWatcher<Result> m_futureWatcher;
  QScopedPointer<Ui::resic> ui;
  Q_SLOT void onResults();
  ...
};

resic::resic(QWidget * parent) : QWidget(parent), ui(new Ui::resic)
{
  connect(&m_futureWatcher, SIGNAL(finished()), SLOT(onResults()));
}

resic::~resic() {}

Parameters resic::get()
{
  Parameters p;
  p.w1=ui->doubleSpinBox_2->value();
  p.um1=ui->doubleSpinBox->value();
  p.alpha1=ui->doubleSpinBox_3->value();
  p.et01=ui->doubleSpinBox_4->value(); 
  ...
  return p; 
}

void resic::on_PushButton_clicked()
{
  Parameters const p(get());
  QFuture<Result> future = QtConcurrent::run(&calculate);
  m_futureWatcher.setFuture(future);
}

void resic::onResults()
{
  Result const r = m_futureWatcher.result();
  ...
}

#2


0  

It is important to remember that a QThread object usually lives in the thread where it was created, not in the thread that it manages. This oft-overlooked detail means that a QThread's slots will be executed in the context of its home thread, not in the context of the thread it is managing. For this reason, implementing new slots in a QThread subclass is error-prone and discouraged.

重要的是要记住,一个QThread对象通常生活在创建它的线程中,而不是它管理的线程中。这个经常被忽略的细节意味着一个QThread的槽将在它的主线程的上下文中执行,而不是在它所管理的线程的上下文中执行。因此,在QThread子类中实现新插槽是容易出错和气馁的。

You can inherit the class "Newton" from QObject create your object of this class on the heap and move it to a new thread.

您可以继承来自QObject的类“Newton”,在堆上创建这个类的对象并将其移动到一个新线程。

It can be done like:

可以这样做:

mythread = new Newton();
QThread * th = new QThread();
mythread->moveToThread(th);

QObject::connect(th,SIGNAL(started()),mythread,SLOT(OnStarted()));
QObject::connect(th,SIGNAL(finished()),mythread,SLOT(OnFinished()));

th->start();

Your initialization and termination tasks in the class Newton should be done in OnStarted() and OnFinished() slots respectively.

在类牛顿中,你的初始化和终止任务应该分别在onstart()和OnFinished()槽中完成。

Now you can implement a slot in your worker thread which runs the calculations. You can connect a signal in your GUI thread to that slot which contains the arguments you want to send. When emitting that signal along the arguments, the calculation slot in the working thread is started with the appropriate arguments.

现在,您可以在工作线程中实现一个运行该计算的槽。您可以在您的GUI线程中连接一个信号到那个包含您想要发送的参数的槽。当在参数中发出该信号时,工作线程中的计算槽以适当的参数开始。

#1


2  

A simple solution to running a piece of code in a worker thread is to leverage Qt Concurrent framework. Another solution is to put the worker into a QObject, and use a QThread directly.

在工作线程中运行一段代码的简单解决方案是利用Qt并发框架。另一种解决方案是将worker放入一个QObject中,并直接使用QThread。

struct Parameters {
  double w1, um1, alpha1, et01, ...;
};

struct Result {
  ...
};

Result calculate(const Parameters & p) {
  ...
}

class resic : public QWidget {
  ...
  QFutureWatcher<Result> m_futureWatcher;
  QScopedPointer<Ui::resic> ui;
  Q_SLOT void onResults();
  ...
};

resic::resic(QWidget * parent) : QWidget(parent), ui(new Ui::resic)
{
  connect(&m_futureWatcher, SIGNAL(finished()), SLOT(onResults()));
}

resic::~resic() {}

Parameters resic::get()
{
  Parameters p;
  p.w1=ui->doubleSpinBox_2->value();
  p.um1=ui->doubleSpinBox->value();
  p.alpha1=ui->doubleSpinBox_3->value();
  p.et01=ui->doubleSpinBox_4->value(); 
  ...
  return p; 
}

void resic::on_PushButton_clicked()
{
  Parameters const p(get());
  QFuture<Result> future = QtConcurrent::run(&calculate);
  m_futureWatcher.setFuture(future);
}

void resic::onResults()
{
  Result const r = m_futureWatcher.result();
  ...
}

#2


0  

It is important to remember that a QThread object usually lives in the thread where it was created, not in the thread that it manages. This oft-overlooked detail means that a QThread's slots will be executed in the context of its home thread, not in the context of the thread it is managing. For this reason, implementing new slots in a QThread subclass is error-prone and discouraged.

重要的是要记住,一个QThread对象通常生活在创建它的线程中,而不是它管理的线程中。这个经常被忽略的细节意味着一个QThread的槽将在它的主线程的上下文中执行,而不是在它所管理的线程的上下文中执行。因此,在QThread子类中实现新插槽是容易出错和气馁的。

You can inherit the class "Newton" from QObject create your object of this class on the heap and move it to a new thread.

您可以继承来自QObject的类“Newton”,在堆上创建这个类的对象并将其移动到一个新线程。

It can be done like:

可以这样做:

mythread = new Newton();
QThread * th = new QThread();
mythread->moveToThread(th);

QObject::connect(th,SIGNAL(started()),mythread,SLOT(OnStarted()));
QObject::connect(th,SIGNAL(finished()),mythread,SLOT(OnFinished()));

th->start();

Your initialization and termination tasks in the class Newton should be done in OnStarted() and OnFinished() slots respectively.

在类牛顿中,你的初始化和终止任务应该分别在onstart()和OnFinished()槽中完成。

Now you can implement a slot in your worker thread which runs the calculations. You can connect a signal in your GUI thread to that slot which contains the arguments you want to send. When emitting that signal along the arguments, the calculation slot in the working thread is started with the appropriate arguments.

现在,您可以在工作线程中实现一个运行该计算的槽。您可以在您的GUI线程中连接一个信号到那个包含您想要发送的参数的槽。当在参数中发出该信号时,工作线程中的计算槽以适当的参数开始。