我写了这样的代码:
myworker.h
class myworker: public QObject
{
Q_OBJECT
private:
int var;
public:
myworker();
~myworker();
signals:
void finished();
public slots:
void chgvar();
void doWork();
};
myworker.cpp
void myworker::doWork()
{
qDebug() <<"doWork "<<"Thread ID: "<< QThread::currentThreadId()<< endl;
while(1){
switch (var)
{
case 1:
emit finished();
};
}
}
myworker::myworker()
{
var=0;
}
myworker::~myworker()
{
}
void myworker::chgvar()
{
var =1;
}
的main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton *var= new QPushButton("chg var");
QPushButton *dowork= new QPushButton("do work");
QHBoxLayout *layout = new QHBoxLayout;
QWidget *window = new QWidget;
layout->addWidget(var);
layout->addWidget(dowork);
window->setLayout(layout);
QThread* thread = new QThread;
myworker* work = new myworker();
QObject::connect(thread, SIGNAL(started()), work , SLOT(dowork()));
QObject::connect(var, SIGNAL(clicked()), work , SLOT(chgvar()));
QObject::connect(work , SIGNAL(finished()), thread, SLOT(quit()));
QObject::connect(work , SIGNAL(finished()), work , SLOT(deleteLater()));
QObject::connect(work , SIGNAL(finished()), thread, SLOT(deleteLater()));*/
work ->moveToThread(thread);
thread->start();
window->show()
return a.exec();
}
当线程启动时,调用插槽dowork,直到变量var等于1.但是当单击改变了var值的按钮(var)时,不会执行插槽。有人能说出是否有错误吗?
感谢您的帮助
答案 0 :(得分:2)
你把工人搬到了线上 - 好动
糟糕的举动是doWork()
具有不定式循环。现在发生的事情是:
started()
doWork()
个槽。doWork()
,并且由于您在doWork()
中有不定式循环,因此会永久占用。chgvar()
位置相同。 Qt检测到目标对象在其他线程中,因此它将chgvar()
chgvar()
(它会在doWork()
完成其工作之前一直存在)热修复吗? 更改连接类型:
QObject::connect(var, SIGNAL(clicked()), work , SLOT(chgvar()), Qt::DirectConnection);
现在其他的多线程问题已经解决,所以你必须使用MUTEX来访问var
,你应该将其标记为volatile
,这样编译器就不会优化对它的访问并破坏代码。
答案 1 :(得分:1)
问题是你的循环永远不会让你的线程进入EventLoop,因此使用一个计时器:
myworker::myworker()
{
var = 0;
timer = new QTimer(this);
timer->setIntervall(100);
connect(timer,SIGNAL(timeout()),this,SLOT(doWork()));
timer->start();
}
void myworker::doWork()
{
qDebug() <<"doWork "<<"Thread ID: "<< QThread::currentThreadId()<< endl;
if(var == 1)
emit finished();
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPushButton *var= new QPushButton("chg var");
QPushButton *dowork= new QPushButton("do work");
QHBoxLayout *layout = new QHBoxLayout;
QWidget *window = new QWidget;
layout->addWidget(var);
layout->addWidget(dowork);
window->setLayout(layout);
QThread* thread = new QThread;
myworker* work = new myworker();
QObject::connect(var, SIGNAL(clicked()), work , SLOT(chgvar()));
QObject::connect(work , SIGNAL(finished()), thread, SLOT(quit()));
QObject::connect(work , SIGNAL(finished()), work , SLOT(deleteLater()));
QObject::connect(work , SIGNAL(finished()), thread, SLOT(deleteLater()));*/
work->moveToThread(thread);
thread->start();
window->show()
return a.exec();
}
答案 2 :(得分:0)
我认为你应该在实际完成循环时发出finished()信号,即当var
的值等于1.我会按以下方式编写函数:
void myworker::doWork()
{
qDebug() << "doWork " << "Thread ID: " << QThread::currentThreadId() << endl;
while(!var){
qDebug() << "Wait...";
}
emit finished();
}
答案 3 :(得分:0)
您的while(1)
循环阻止了事件循环。事件永远不会被处理。这就是你永远不会调用你的插槽的原因。你应该考虑使用QTimer
。请阅读this了解详情。
答案 4 :(得分:0)
您的代码中存在两个问题: