2013-04-02 97 views
3

我正在使用Qt编写GUI应用程序。创建qt线程事件循环

一个主线程负责GUI并创建一个QThread以便与一个对象做一些工作。

class Worker 
{ 
    void start() { 
     QTimer* timer = new Timer(); 
     connect(timer,SIGNAL(timeout()),this,SLOT(do())); 
    } 

    void do() { 
     //do some stuff 
     emit finished(); 
    } 
} 



class GUI 
{ 
    //do some GUI work then call startWorker(); 

    void startWorker() { 
     QThread* thread = new Thread(); 
     Worker* worker = new Worker(); 

     worker->moveToThread(thread); 

     connect(thread, SIGNAL(started()), worker, SLOT(start())); 
     connect(worker, SIGNAL(finished()), workerthread, SLOT(quit())); 
     connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); 
    } 
} 

现在我有几个问题:

  1. 我工人阶级定时器不起作用。也许这是因为new thread has no event loop,但我不知道如何创建这样一个。我试图

    connect(workerthread, SIGNAL(started()), workerthread, SLOT(exec()));

    ,但它也不起作用。

  2. 当我尝试等待新的线程,信号不会发送

    class GUI 
    { 
        void exit() { 
         thread->wait(); 
        } 
    } 
    

我想这也就是因为没有事件循环,并因为没有信号发出。

有没有人有一个想法如何解决这些问题?

+0

你忘了在你的线程中调用[开始](http://qt-project.org/doc/qt-4.8/qthread.html#start)吗?这不在你的代码示例中。 – cgmb

回答

1

为什么不使用qthreadpool,使您的任务类从qrunnable和qobject继承,这样您就可以使用信号和插槽将数据从一个线程传递到另一个线程,实现起来更简单,并且不会重新创建一个线程或有一个睡所有的时间

class myTask : public QObject, public QRunnable{ 
Q_OBJECT 

protected: 
void run(); //where you actually implement what is supposed to do 

signals: 
void done(int data);//change int to whatever data type you need 

} 

//moc click example, or use a timer to call this function every x amount of time 
void button_click(){ 
    myTask *task = new myTask(); 
    task->setAutoDelete(true); 
    connect(task,SIGNAL(done(int)),this,SLOT(after_done(int)),Qt::QueuedConnection); 
    QThreadPool::globalInstance()->start(task); 
} 

默认情况下,你的应用程序自动获得1个线程,你可以用它来处理图形,不是使用qthreadpool处理按需提供数据/对象,你甚至可以设置应用程序可用于处理新请求的线程的最大数量,其他线程将保留在队列中,直到释放一个线程为止

QThreadPool::globalInstance()->setMaxThreadCount(5); 
+0

谢谢,这是一个非常简单的解决方案,我将来会使用它。但是现在我决定为当前的问题使用另一种解决方案,因为我想要在另一个线程中经常工作。现在我的解决方案是实现一个自己的线程和使用exec()有一个事件循环在其中 –

+0

听起来不错,我也希望你注意到,它确实使用第二个线程(在我的情况下最多5个线程在同一时间) ,一旦任务完成,线程不会被破坏,它会被重用,在所有线程都很昂贵之后提高性能。总之,很高兴能够帮助 – Sherlock

2

这是一个示例代码为您:

QThread* thread = new QThread(); 
Worker* worker = new Worker(3000); 
worker->moveToThread(thread); 
QObject::connect(thread, SIGNAL(started()), worker, SLOT(start())); 
thread->start();` 

class Worker : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit Worker(qint32,QObject *parent = 0); 
    qint32 myTime; 

signals: 
    void workFinished(); 

public slots: 
    void doWork(); 
    void start(); 
    private: 
    QTimer *timer; 
}; 


#include "worker.h" 
#include <QTimer> 
#include <QDebug> 
Worker::Worker(qint32 t,QObject *parent) : 
    QObject(parent) 
{ 
    myTime=t; 
} 

void Worker::start() 
{ 
    timer = new QTimer(); 
    timer->start(myTime); 
    qDebug()<<QString("start work in time:%1").arg(myTime); 
    connect(timer,SIGNAL(timeout()),this,SLOT(doWork())); 
} 

void Worker::doWork() 
{ 
    qDebug()<<"dowork"; 
    timer->stop(); 
    emit workFinished(); 
} 

Debug结果:

start work in time:3000

我希望这可以帮助你。

+0

是的,但现在我决定使用另一种解决方案。我正在使用自己实施的线程 –

+0

@SvenJung这是接受的答案吗?我需要声望,所以如果是,请设置它。 – Aliceljm