如何修复运行时崩溃 - QObject :: setParent:无法设置父级,新父级是否在不同的线程中?

时间:2014-04-17 09:15:07

标签: c++ qt qthread

我编写了一个QT - webkit应用程序。当我的pSeudo驱动程序获得字符'l'时,此应用程序将触发回调。但是,应用程序在firecallback期间崩溃 - 它说 - QObject :: setParent:无法设置父级,新父级位于不同的线程中。我不知道要解决这个问题,我尝试做moveToThread,但它没有帮助。请帮帮我。

#include <QtGui/QApplication>
#include <QApplication>
#include <QDebug>
#include <QWebFrame>
#include <QWebPage>
#include <QWebView>
#include <QThread>

#include <unistd.h>
#include <fcntl.h>


class DemoThread;

class MyJavaScriptOperations : public QObject {
    Q_OBJECT
 public: 
 QWebView *view;
 DemoThread *m_pDemoThread;
  MyJavaScriptOperations();
  void firecb();
  bool slot_installed;
 signals:
 void  alert_script_signal();
public slots:
  void JS_ADDED();
  void loadFinished(bool);

private:

};

 class DemoThread : public QThread {
     public:

    DemoThread( MyJavaScriptOperations *pJavascriptOp);
    protected:
        void run();
    private :

    MyJavaScriptOperations *m_pJavascriptOp;
    };

DemoThread::DemoThread(MyJavaScriptOperations *pJavascriptOp):m_pJavascriptOp(pJavascriptOp)
{

}

void DemoThread:: run()
{
  int filedesc = open("/dev/pSeudoDrv", O_RDONLY);
    if(filedesc < 0)
      {
          qDebug()<<"Couldn't open Driver.";  
      }

   unsigned char buff;

  while(1)
  {
    read(filedesc,&buff, 1);

    qDebug()<<"The code received is "<< buff;

    if ( (m_pJavascriptOp->slot_installed == true)  && (buff == 166))
    {
      m_pJavascriptOp->firecb();    

    }
    qDebug()<<"Running Thread.";
    sleep(6);

  } 
}

void MyJavaScriptOperations::JS_ADDED()
{
  qDebug()<<__PRETTY_FUNCTION__;
  view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", this); 
}

void MyJavaScriptOperations::loadFinished(bool oper)
{
  qDebug()<<__PRETTY_FUNCTION__<< oper;
  slot_installed = true;

 // firecb();

}

void MyJavaScriptOperations::firecb()
{
  qDebug()<<__PRETTY_FUNCTION__;
  view->page()->mainFrame()->evaluateJavaScript("JavaScript_function()");
}

MyJavaScriptOperations::MyJavaScriptOperations()
{
    qDebug()<<__PRETTY_FUNCTION__;
    view = new QWebView();
    view->resize(400, 500);
    connect(view->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(JS_ADDED()));
    connect(view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
    view->load(QUrl("./index.html"));
    view->show();

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MyJavaScriptOperations *jvs = new MyJavaScriptOperations;
    DemoThread *thread = new DemoThread(jvs);
    jvs->moveToThread(thread);
    thread->start();
    return a.exec();
}
#include "main.moc"

这是我得到的崩溃错误 -

./QT_DEMO 
MyJavaScriptOperations::MyJavaScriptOperations() 
loaded the Generic plugin 
The code received is  156 
Running Thread. 
The code received is  166 
void MyJavaScriptOperations::firecb() 
QObject::setParent: Cannot set parent, new parent is in a different thread

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:0)

好吧,我找到了解决问题的方法。请告诉我,我是否使解决方案复杂化。 我正在使用信号和插槽。线程将发出信号,其他类的槽将发出回调到Qtwebkit - javascript函数。这样对吗? 因为,我建议使用事件循环 - exec()。

#include <QtGui/QApplication>
#include <QApplication>
#include <QDebug>
#include <QWebFrame>
#include <QWebPage>
#include <QWebView>
#include <QThread>

/** for reading my driver **/
#include <unistd.h>
#include <fcntl.h>


class DemoThread;

class MyJavaScriptOperations : public QObject
{
    Q_OBJECT

 public:

  QWebView *view;
  DemoThread *m_pDemoThread;
  MyJavaScriptOperations();
  void firecb();
  bool slot_installed;

signals:
 void  alert_script_signal();

public slots:
  void JsAdded();
  void alertReceived();
  void loadFinished(bool);

private:

};

 class DemoThread : public QThread
 {

Q_OBJECT

 private:

 MyJavaScriptOperations *m_pJavascriptOp;

 public:

    DemoThread( MyJavaScriptOperations *pJavascriptOp);

 protected:
        void run();

 signals:
        void  alertSendSignal();
};


 DemoThread::DemoThread(MyJavaScriptOperations *pJavascriptOp):m_pJavascriptOp(pJavascriptOp)
{
  connect(this, SIGNAL(alertSendSignal()), m_pJavascriptOp, SLOT(alertReceived()));

}

void DemoThread:: run()
{
  int filedesc = open("/dev/pSeudoDrv", O_RDONLY);

  if(filedesc < 0)
      {
          qDebug()<<"Couldn't open Driver.";
      }

  unsigned char buff;

  while(1)
  {
    if( 1 != read(filedesc,&buff, 1))
    {
        qDebug()<<"Read Invalid Data";
    }

    qDebug()<<"The code received is "<< buff;

    /** In my laptop, the 166 means the character 'l' **/
    if ( (m_pJavascriptOp->slot_installed == true)  && (buff == 166))
    {
        emit alertSendSignal();
    }
    qDebug()<<"Running Thread.";

  }
}

void MyJavaScriptOperations::JsAdded()
{
  qDebug()<<__PRETTY_FUNCTION__;
  view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", this);
}

void MyJavaScriptOperations::loadFinished(bool oper)
{
  qDebug()<<__PRETTY_FUNCTION__<< oper;
  slot_installed = true;
}

void MyJavaScriptOperations::alertReceived()
{
    qDebug()<<"Sending Firecallback now";
    firecb();
}

void MyJavaScriptOperations::firecb()
{
  qDebug()<<__PRETTY_FUNCTION__;
  view->page()->mainFrame()->evaluateJavaScript("JavaScript_function()");
}

MyJavaScriptOperations::MyJavaScriptOperations()
{
    qDebug()<<__PRETTY_FUNCTION__;
    view = new QWebView();
    view->resize(400, 500);
    connect(view->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(JsAdded()));
    connect(view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
    view->load(QUrl("./index.html"));
    view->show();

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyJavaScriptOperations *jvs = new MyJavaScriptOperations;
    DemoThread *thread = new DemoThread(jvs);
    thread->start();
    return a.exec();
}
#include "main.moc"