【问题标题】:Qt Object::connect: No such slot Signal to Thread SlotQt Object::connect: No such slot Signal to Thread Slot
【发布时间】:2012-10-26 07:26:28
【问题描述】:

我尝试在线程启动时调用线程对象中的 Slot 但收到此错误:

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 *&);

};

【问题讨论】:

    标签: c++ qt signals-slots


    【解决方案1】:
    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());
    }
    

    【讨论】:

    • 我想避免将成员保留在 Worker 对象中,以使 pFoo 引用指向指针
    • 然后在您的主类中创建一个不带参数的私有插槽,并将其连接到您的工作线程的start() 信号。在您的私人插槽中调用m_WorkerThread->doWork((pfooStack))
    • 我在这里很困惑你是什么意思? .. 好的,你 .. 它是线程安全的吗?
    • 只要InternalStorageManager::getInstance()->getStack()是。
    【解决方案2】:

    我没有在我的电脑上编译代码,但它应该暗示你需要什么:

         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;
    
    };
    

    【讨论】:

    • 这没问题,但我想避免保留 FooStack 成员
    【解决方案3】:

    你不能那样做,你不能在connect中将当前变量作为槽方法参数传递,槽不能有比信号更多的参数。除了其他答案之外,您还可以使用 QSignalMapper 实现此目的,但如果您只有一个与插槽的连接,那似乎有点过头了。

    如果您可以使用 Qt5 和 C++11,那么您可以将信号连接到 lambda 函数,而不仅仅是插槽,但我不确定这是否支持创建闭包(即使用lambda 函数,这里需要用到)。

    【讨论】:

      【解决方案4】:

      我认为您需要更改信号和插槽签名。来自 QT 文档:

      关于是否在 SIGNAL() 和 SLOT() 宏中包含参数的规则,如果参数具有默认值,则传递给 SIGNAL() 宏的签名的参数不得少于传递的签名到 SLOT() 宏。

      【讨论】:

      • 我想我需要使用一些 QSignalMapper
      • 我认为更好的解决方案是重新考虑您的类设计,或者将 pFooStack 传递给构造函数并将其存储在内部(如 Ruby 建议的那样),或者每次在 doWork 时获取您的 InternalStorageManager。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多