我有一个设置,需要通过蓝牙连接到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)
由于存在未知数量的子代,因此无法选择使用信号在主线程和子代线程之间进行通信。