如何克服Qthread同步问题?

时间:2014-02-26 06:30:25

标签: multithreading qt

我有一个加载网页并显示它的主线程。我有另一个线程正在运行,它只是将调试消息打印到控制台。但是,我看到在运行QT-Thread时,网页没有被加载。我尝试将网页加载到线程的构造函数上,但这也没有帮助。这就是代码。

class MyJavaScriptOperations : public QObject {
    Q_OBJECT
public:

    Q_INVOKABLE qint32 MultOfNumbers(int a, int b) {
        qDebug() << a * b;
        return (a*b);
    }
};


#if 1

class MyThread : public QThread
{
    Q_OBJECT

public:
    MyThread();

public:
    void run();
};

MyThread::MyThread()
{
    qDebug()<<"Constructor called";
    QWebView *view = new QWebView();
    view->resize(400, 500);
    view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", new MyJavaScriptOperations);
    view->load(QUrl("./shreyas.html"));
    view->show();
    this->run();
}



void MyThread::run()
{
    qDebug()<<"Thread running";

    while(1)
     {
       qDebug()<<"Fire Callback now";
     }

}
#endif


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

    MyThread t;
    //t.run();



    return a.exec();
}

1 个答案:

答案 0 :(得分:1)

仅仅因为代码在QThread的子类中并不意味着代码在该线程中执行。您的主线程构造对象,该构造函数调用run()。这意味着run方法的代码仍然在主线程中执行,并且 - 因为它是阻塞的 - 从不调用行a.exec(),并且主线程永远不会获得事件循环油漆事件等所需。

您需要做的是启动线程并等待run()被执行:

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

    // TODO: Code for your web view goes here. You will probably need to
    //       pass the created web view into the constructor of MyThread

    MyThread t;
    // start the thread - this will put an event in the main event loop
    t.start();

    // start the event loop - this will lead to MyThread::run() being called
    return a.exec();
}

这足以让您的示例运行,但是在关闭Web视图时会出现错误,因为您使用线程的方式不是预期的:如果您想使代码稳定,请将{{{ 1}}一个单独的工人类中的方法,并使用默认的run()来管理它,而不用子类化QThread

我建议阅读Qt5 Documentation on threads,这也适用于早期版本的Qt。