2012-10-26 134 views
0

我嘗試在線程對象調用插槽時threas開始,但得到這個錯誤:Qt對象::連接:沒有這樣的插槽信號主題插槽

Object::connect: No such slot Worker::doWork(pFoo) 

線程執行代碼:

// main class 

      m_WorkerThread = new QThread(); 

      FooStack* pfooStack = InternalStorageManager::getInstance()->getStack(); 
      m_Worker = new Worker(); 
      bool done = connect(m_WorkerThread, 
            SIGNAL(started()), 
            m_Worker, 
            SLOT(doWork(pfooStack))); 

      m_Worker->moveToThread(m_WorkerThread);   
      m_WorkerThread->start(); 



// class Worker 
// cpp imple    
void Worker::doWork(FooStack *& rp_urlsStack) 
{ 

} 
// header 
class Worker : public QObject 
{ 

    Q_OBJECT 

    public : 

     Worker(); 
     ~Worker(); 
    public slots: 
     void doWork(FooStack *&); 

}; 

回答

3
Object::connect: No such slot Worker::doWork(pFoo) 

您不能在連接聲明中傳遞對象。

難道你不能將pfooStack傳遞給Worker的構造函數嗎?

編輯:

class Main : ... 
{ 
    ... 
    void startThread(); // The method in your example. 
private slots: 
    void startWork(); 
    ... 
}; 

void Main::startThread() 
{ 
    m_WorkerThread = new QThread(); 
    m_Worker = new Worker(); 
    bool done = connect(m_WorkerThread, SIGNAL(started()), 
         this, SLOT(startWork())); 

    m_Worker->moveToThread(m_WorkerThread);   
    m_WorkerThread->start(); 
} 

void Main::startWork() 
{ 
    m_Worker->doWork(InternalStorageManager::getInstance()->getStack()); 
} 
+0

我想避免保留pFoo的Worker對象中的成員參考指針 – user63898

+0

然後在您的主類中創建一個不帶參數並將其連接到工作線程的'start()'信號的專用插槽。在您的專用槽插槽內調用'm_WorkerThread-> doWork((pfooStack))'。 – cmannett85

+0

即時在這裏困惑你是什麼意思? ..好吧gotyou ..線程安全嗎? – user63898

0

我認爲你需要改變信號和插槽的簽名。從QT Documenation:

The rule about whether to include arguments or not in the SIGNAL() and SLOT() macros, if the arguments have default values, is that the signature passed to the SIGNAL() macro must not have fewer arguments than the signature passed to the SLOT() macro.

+0

我想我需要使用QSignalMapper – user63898

+0

我認爲更好的解決方案是重新考慮您的類設計,要麼將pFooStack傳遞給構造函數並將其存儲在內部(如Rubby建議的),要麼每次使用doWork時獲取InternalStorageManager '。 – AquilaRapax

1

我還沒有編機上的代碼,但它應該意味着你需要什麼:

 m_WorkerThread = new QThread(); 

      FooStack* pfooStack = InternalStorageManager::getInstance()->getStack(); 
      m_Worker = new Worker(pfooStack); 
      bool done = connect(m_WorkerThread, 
            SIGNAL(started()), 
            m_Worker, 
            SLOT(doWork())); 

      m_Worker->moveToThread(m_WorkerThread);   
      m_WorkerThread->start(); 




void Worker::doWork() 
{ 
     //use stack here 
} 

class Worker : public QObject 
{ 

    Q_OBJECT 

    public : 

     Worker(FooStack *& rp_urlsStack):stack(rp_urlsStack); 
     ~Worker(); 
    public slots: 
     void doWork(); 
    private: 
     FooStack*& stack; 

}; 
+0

這是行不通的,但我喜歡避免保留FooStack成員 – user63898

1

你不能這樣做的,你不能在連接中將電流變量作爲插槽方法參數傳遞,並且插槽的參數不能超過信號。除了其他答案之外,您可以通過QSignalMapper來實現此目的,但是如果您只有一個連接到插槽,那似乎是一種矯枉過正。

如果您可以使用Qt5和C++ 11,那麼您可以將信號連接到lambda函數,而不僅僅是插槽,但我不確定是否支持創建閉包(即使用局部變量lambda函數,你需要在這裏)。