2012-10-26 137 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函数,你需要在这里)。