对象:无法为处于不同线程中的父级创建子级

时间:2019-07-17 08:02:00

标签: c++ qt

我正在使用:

Qt Creator 3.0.1
Based on Qt 5.2.1 (GCC 4.8.2, 32 bit)
Built on Apr 9 2014 at 09:14:10

此版本是ACR890 SDK的一部分,全部集成在一个移动智能卡终端中。

手机正在运行linux,如果运行,我的发行版就不是这样:

uname -a:

我得到:

Linux am37x-evm 2.6.37 #1 Wed Nov 22 18:16:43 HKT 2017 armv7l GNU/Linux

在我的应用程序中,我创建一个工作线程来检查WiFi网络的状态:

mpWiFiScan = new clsWiFiScan(this);
//Connect slot to scan signal
connect(mpWiFiScan, SIGNAL(scanResultsReady(QString))
           ,this, SLOT(networkScanResults(QString)));
mpWiFiScan->setScanState(SS_SCAN);
mpWiFiScan->start();

这在主窗口构造函数的末尾被调用。在主窗口类中,我有一个插槽可以接收网络扫描结果:

void clsMainWnd::networkScanResults(QString strResults) {
    qDebug() << "clsMainWnd::networkScanResults:";
    qDebug() << strResults;
}

这是WiFi扫描线程主体:

void clsWiFiScan::run() {
    int intSleepCounter = 0;
    bool blnLastPowerState;
    QString strResponse;

    while ( true ) {
        eScanState eState = eGetScanState();

        if ( eState == SS_TERMINATE ) {
            break;
        }
        if ( eState != SS_SCAN ) {
            continue;
        }
        bool blnPower = blnGetPowerStatus();

        if ( blnPower != true ) {
    //Is the "wpa_supplicant" process running?
            if ( clsSOAP::lngPIDof(this, lsWiFiScan::mscstrWPAsupplicant) == 0 ) {
    //No, start it now
                mpcAcsWiFi->reloadWpaSupplicant();
            }
    //Can we ping Google?
            if ( clsSOAP::blnPingTest(this) != true ) {
    //No, ensure WiFi power is on
                wifi_pwr_on();
            }
    //Can we get a server response?
            strResponse = mpcAcsWiFi->status();

            if ( strResponse.contains("wpa_state=COMPLETED") ) {
    //Yes, turn on power
                setPower(true);
            }
            while ( eState != SS_TERMINATE
                 && eState != SS_PAUSE
                 && intSleepCounter < mscintReloadWPAsupplicantTime) {
                sleep(mscintTempSleepDuration);
                intSleepCounter += mscintTempSleepDuration;
                eState = eGetScanState();
            }
            if ( intSleepCounter == mscintReloadWPAsupplicantTime ) {
                setPower(true);
            }
            intSleepCounter = 0;
        }
    //If the power was off and now its on...
        if ( blnLastPowerState != true && blnGetPowerStatus() == true ) {
            mpcAcsWiFi->scan();
            strResponse = mpcAcsWiFi->scanResults();
            emit scanResultsReady(strResponse);

            while ( eState != SS_TERMINATE
                 && eState != SS_PAUSE
                 && intSleepCounter < mscintScanInterval ) {
                sleep(mscintTempSleepDuration);
                intSleepCounter += mscintTempSleepDuration;
                eState = eGetScanState();
            }
        }
    //Update the last known power state
        blnLastPowerState = blnPower;
        intSleepCounter = 0;
    }
    emit scanFinished();
    delete mpcAcsWiFi;
    setScanState(SS_TERMINATED);
}

问题是当我运行此应用程序时,我看到许多以下内容:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is clsWiFiScan(0xd8208), parent's thread is Thread(0xb8c38), current thread is clsWiFiScan(0xd8208)

然后再来

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QProcess(0xd82e8), parent's thread is Thread(0xb8c38), current thread is clsWiFiScan(0xd8208)
在功能中调用

QProcess:

bool clsSOAP::blnPingTest(QObject* pParent, QString strURL) {
    QProcess* pProc = new QProcess(pParent);
    pProc->start("ping", QStringList() << "-c" << "1" <<
                                          "-w" << "10" <<
                                          strURL);
    while( pProc->waitForFinished() != true ) {
    }
    int intExitCode = pProc->exitCode();
    delete pProc;
    return (intExitCode == 0);
}
对于Google,

strURL的默认值为8.8.8.8。

long clsSOAP::lngPIDof(QObject* pParent, QString strApp) {
    QProcess* pProc = new QProcess(pParent);
    pProc->start("pidof", QStringList() << strApp);
    while( pProc->waitForFinished() != true ) {
    }
    QByteArray bytOutput = pProc->readAllStandardOutput();
    bool blnOk;
    long lngPID = bytOutput.trimmed().toLong(&blnOk);
    delete pProc;
    return lngPID;
}

一切似乎都可以,但是我仍然收到很多这样的警告。

[EDIT]基于注释,我更改了类,因此它现在是从QObject而不是QThread派生的。

它现在显示为:

mpWiFiScan = new clsWiFiScan(this);
//In the clsWiFiScan constructor it calls setParent(pParent); where pParent the passed parameter
mpWiFiScan->moveToThread(&mthrdWiFiScan);
//mthrdWiFiScan is a member variable of type QThread
connect(&mthrdWiFiScan, SIGNAL(started())
       ,mpWiFiScan, SLOT(run()));
connect(mpWiFiScan, SIGNAL(scanFinished())
       ,&mthrdWiFiScan, SLOT(quit()));
connect(mpWiFiScan, SIGNAL(scanFinished())
       ,&mthrdWiFiScan, SLOT(deleteLater()));
connect(&mthrdWiFiScan, SIGNAL(finished())
       ,&mthrdWiFiScan, SLOT(deleteLater()));
mthrdWiFiScan.start();

我仍然收到相同的消息,而且根本看不到run()被调用。

1 个答案:

答案 0 :(得分:1)

您可以通过调用QObject::moveToThread()然后设置父项来解决这些问题。

例如,您创建WiFi扫描器的代码将像这样更改。

//section[contains(@class, 'srpCards') and not(.//img[contains(@src, 'soldOut')])]