2013-04-12 3 views
1

Я занимаюсь потоками в Qt. Я переоценил run() (хотя это не рекомендуется), и все сработало нормально.Повторное выполнение start() QThread

Теперь я хочу добавить дополнительную функциональность в run(), передав ей переменную: run(int i). Кроме того, я хочу start(), который вызывает прогон, чтобы передать переменную run(int i): start(int j).


Я думал, реализовав старт следующим образом должен работать: (Zaehler является QThread)

void Zaehler::start(int ZaehlerIndex) { run(ZaehlerIndex), terminate(); }

Ну это не так. Мой графический интерфейс зависает при запуске потока.


Вопрос: Я знаю, баловаться с начала и следует избегать бега, но есть способ сделать это? Я делаю что-то неправильно?

Примечание: Я посмотрел qthread.cpp, чтобы увидеть, как start() реализуется, но все, что я нашел, было

\sa run(), terminate() который закомментирована! Так что это на самом деле не должно даже работать !?

+0

вы решили свой вопрос? – loentar

ответ

0

Как насчет чего-то подобного?

class Worker 
{ 
    //note, only pass parameters by copy here. 
    public: 
     Worker(int param) : myParam(param) {} 

    public slots: 
     void process() 
     { 
      //do something with myParam here, it will run in the thread. 
     } 

    signals: 
     void finished(); 
     void error(QString err); 

    private: 
     int myParam; 
}; 

, который затем может быть подключен к объекту потока с помощью «moveToThread» как так:

QThread* thread = new QThread; 
Worker* worker = new Worker(5); 
worker->moveToThread(thread); 
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString))); 
connect(thread, SIGNAL(started()), worker, SLOT(process())); 
connect(worker, SIGNAL(finished()), thread, SLOT(quit())); 
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); 
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 
thread->start(); 

Смотрите здесь для получения дополнительной информации и краткое руководство по использованию потоков в Qt: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

0

, если вы хотите, чтобы начать функцию внутри нити и передать некоторые аргументы этой функции я рекомендовал этот метод:

class MyWorker: public QThread 
{ 
    Q_OBJECT 
public: 
    MyWorker() 
    { 
     start(); 
    } 

    virtual ~MyWorker() 
    { 
     quit(); 
     wait(); 
    } 

    // your function to call inside thread 
    Q_INVOKABLE void doSomeWork(int data) 
    { 
     // check if we called from another thread 
     if (QThread::currentThread() != this) 
     { 
      // re-call self from very own thread 
      QMetaObject::invokeMethod(this, "doSomeWork", 
             Qt::BlockingQueuedConnection, 
      // or Qt::QueuedConnection if you want to start it asynchronously 
      // and don't wait when work finished 
             Q_ARG(int, data)); 
      return; 
     } 

     // this will be started within your thread 
     // some useful work here 
    } 
}; 

Если поток не имеет какого-либо метода Run() QEventLoop будет использоваться, и вы можете вспомнить ваш метод в контексте потока.

Кроме того, вместо Q_INVOKABLE вы можете объявить свой метод в качестве слота и вызвать его с помощью очередного соединения.