【问题标题】:Sending parameters from GUI thread to work thread将参数从 GUI 线程发送到工作线程
【发布时间】:2014-04-02 20:46:10
【问题描述】:

我在 Qt 中遇到了一些问题。 我在 GUI 线程中分配了一些参数:

newton.h(工作线程):

class Newton : public QThread

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();
}

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

非常感谢。

【问题讨论】:

标签: c++ qt user-interface parameter-passing qthread


【解决方案1】:

在工作线程中运行一段代码的简单解决方案是利用 Qt Concurrent 框架。另一种解决方案是puttheworkerintoa 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】:

    重要的是要记住QThread 对象通常存在于创建它的线程中,而不是它管理的线程中。这个经常被忽视的细节意味着QThread 的槽将在其主线程的上下文中执行,而不是在它所管理的线程的上下文中。出于这个原因,在QThread 子类中实现新插槽容易出错并且不鼓励。

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

    可以这样做:

    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();
    

    Newton 类中的初始化和终止任务应分别在 OnStarted()OnFinished() 插槽中完成。

    现在您可以在运行计算的工作线程中实现一个槽。您可以将 GUI 线程中的信号连接到包含您要发送的参数的插槽。当沿参数发出该信号时,工作线程中的计算槽会以适当的参数启动。

    【讨论】:

      猜你喜欢
      • 2011-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 2015-10-19
      • 2011-03-25
      相关资源
      最近更新 更多