线程子项的Qt访问方法

时间:2019-05-07 07:10:00

标签: c++ multithreading qt

我有一个设置,需要通过蓝牙连接到X个物理按钮。由于所有按钮将以某种方式一起交互,因此我需要一个类来封装它们之间的所有通信。所以我写了这个课:

class ButtonControls : public QThread
{
    Q_OBJECT
public:

    ButtonControls(){
        this->moveToThread(this);
    }
    virtual ~ButtonControls();

    void free();
    void init(ButtonConfig* buttonconfig){
        foreach(ButtonThreadData* btnData, buttonconfig->getAllButtons())
        {
            addButtonThread(btnData);
            msleep(500);
        }
    }
    void startThread();
    void stopThread();

public slots:
    void onSetButtonValue(QString keyname, uint value){
        m_btnThread = m_buttonThreadMap.value(keyname, NULL);
        if(m_btnThread){
            m_btnThread->setValue(value);
        }
    }
    void onButtonPressed(QString keyname);

private:
    QMap<QString, ButtonThread*> m_buttonThreadMap;

    void addButtonThread(ButtonThreadData* btn_data)
    {
        ButtonThread *buttonThread = new ButtonThread(this);
        buttonThread->init(btn_data);

        QObject::connect(buttonThread, SIGNAL(sigButtonPressed(QString)), this, SLOT(onButtonPressed(QString)), Qt::QueuedConnection);
        QThreadPool::globalInstance()->start(buttonThread);

        buttonThread->startConnection();

        m_buttonThreadMap.insert(btn_data->getKeyname(), buttonThread);
    }

};

此类基本上接收数据的配置列表(是的,我知道存在QList类,但是我需要扩展功能),并为配置中的每个按钮创建一个线程,并建立从线程到主人。

子级ButtonThread类如下所示:

class ButtonThread : public QThread, public QRunnable
{
    Q_OBJECT

public:
    ButtonThread(QThread* parent){
        m_parent = parent;
    }
    void startThread();
    void stopThread();

    init(ButtonThreadData* btnData);
    startConnection();

    setValue(uint8_t){
        //do some bluetooth communication
    }
signals:
    sigButtonPressed(QString keyname);
private:
    QThread* m_parent;
}

在ButttonThread中,我没有执行任何“线程移动”操作,它具有每个线程必须的启动,停止和运行方法。

问题是由直接从ButtonControls :: onSetButtonValue插槽内调用ButtonThread :: setValue引起的。我收到通常的消息:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QLowEnergyControllerPrivateBluezDBus(0x7488a988), parent's thread is QThread(0xaeca0), current thread is ButtonControls(0xaf720)

由于存在未知数量的子代,因此无法选择使用信号在主线程和子代线程之间进行通信。

0 个答案:

没有答案