Reputation: 25
I have got some problem in Qt. I assign some parameters in GUI thread:
newton.h (work thread) :
class Newton : public QThread
resic.cpp (GUI thread) :
.
.
.
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.
Upvotes: 1
Views: 481
Reputation: 32635
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.
You can inherit the class "Newton" from QObject
create your object of this class on the heap and move it to a new thread.
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.
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.
Upvotes: 0
Reputation: 98425
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.
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();
...
}
Upvotes: 2