2014-01-21 53 views
0

我使用pyqt/webkit運行html文件。 我使用evaluateJavascript在onload回調中設法與dom一起玩。不幸的是,如果我試圖在其他地方(在Qthread內)做到這一點。我無法使用DOM。需要注意的是評估的JavaScript工作正常(我能做例如警報)PYQT:在QThread中使用evaluatejavascript時無法達到DOM

的代碼如下:

index.html文件:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
    <head> 
    <title>test</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
</head> 
    <body> 
     <div id="info">test</div> 
</body> 
</html> 

和Python文件:

import sys 
import time 
import PyQt4 
from PyQt4.QtCore import Qt 
from PyQt4.QtGui import QPalette, QGraphicsScene, QGraphicsProxyWidget, QGraphicsView, QPainter 
from PyQt4.QtOpenGL import QGLWidget 
from PyQt4.QtCore import QObject, pyqtSlot, QUrl 
from PyQt4.QtGui import QApplication 
from PyQt4.QtWebKit import QWebView, QWebSettings 
from PyQt4 import QtCore, QtGui, QtWebKit 

global frame 



class testQthread(QtCore.QThread): 
    def __init__(self): 
     QtCore.QThread.__init__(self) 


    def run(self): 
     global frame 
     print "****************** IN THREAD 1******************" 
     time.sleep(2) 
     print frame 
     frame.evaluateJavaScript(' document.getElementById("info").innerHTML="should work here";') 
     while True: 
      time.sleep(1) 



class WithConsole(QtWebKit.QWebPage): 
    def javaScriptConsoleMessage(self, msg, line, source): 
     print '%s line %d: %s' % (source, line, msg) 


class HTMLApplication(object): 

    def show(self): 
     #It is IMPERATIVE that all forward slashes are scrubbed out, otherwise QTWebKit seems to be 
     # easily confused 

     #This is basically a browser instance 
     self.web = QWebView() 
     self.web.setAttribute(Qt.WA_X11NetWmWindowTypeDesktop) 
     self.web.setAttribute(Qt.WA_OpaquePaintEvent, True) 
     self.settings=self.web.settings() 
     self.settings.setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True) 
     self.settings.setAttribute(QWebSettings.LocalContentCanAccessFileUrls, True) 
     self.settings.setAttribute(QWebSettings.LocalStorageEnabled, True) 
     self.settings.setAttribute(QWebSettings.AutoLoadImages, True) 
     page = WithConsole() 
     self.web.setPage(page) 

     #Unlikely to matter but prefer to be waiting for callback then try to catch 
     # it in time. 
     self.web.loadFinished.connect(self.onLoad) 

     self.web.load(QUrl("index.html")) 
     self.web.show() 

    def onLoad(self): 
     global frame 
     #This is the body of a web browser tab 
     self.myPage = self.web.page() 
     self.myPage.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) 
     self.myFrame = self.myPage.mainFrame() 
     self.myFrame.evaluateJavaScript(' document.getElementById("info").innerHTML="work fine inside onLoad";') 
     frame=self.myFrame 




if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    global frame 

    myWebApp=HTMLApplication() 
    myWebApp.show(); 
    d=testQthread() 
    d.start() 
    app.exec_() 

回答

0

我發現了這個問題。 pb只是說gui只能被同一個線程調用。我們必須使用信號插槽的東西。 良好的執行應該是:

import sys 
import time 
import PyQt4 
from PyQt4.QtCore import Qt 
from PyQt4.QtGui import QPalette, QGraphicsScene, QGraphicsProxyWidget, QGraphicsView, QPainter 
from PyQt4.QtOpenGL import QGLWidget 
from PyQt4.QtCore import QObject, pyqtSlot, QUrl 
from PyQt4.QtGui import QApplication 
from PyQt4.QtWebKit import QWebView, QWebSettings 
from PyQt4 import QtCore, QtGui, QtWebKit 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

class MyThread(QThread): 
    def __init__(self, name): 
     super(MyThread, self).__init__() 
     self.setObjectName(name) 

    def run(self): 
     print "RUN", QThread.currentThread().objectName(), QApplication.instance().thread().objectName() 
     self.exec_() 
     print "RUN DONE", QThread.currentThread().objectName() 

class Producer(QObject): 
    def __init__(self, parent=None): 
     super(Producer, self).__init__(parent) 

    def Start(self): 
     for i in range(5): 
      print "Producer",i,QThread.currentThread().objectName() 
      self.emit(SIGNAL("jseval"),'document.getElementById("info").innerHTML="yes I cans";') 
      time.sleep(2) 
     time.sleep(1) 
     qApp.quit() 

class Browser(QObject): 
    def __init__(self, parent=None): 
     super(Browser, self).__init__(parent) 

    def jseval(self, val): 
     self.myFrame.evaluateJavaScript(val) 


    def show(self): 
     self.web = QWebView() 
     self.web.loadFinished.connect(self.onLoad) 
     self.web.load(QUrl("index.html")) 
     self.web.show() 

    def onLoad(self): 
     self.myPage = self.web.page() 
     self.myFrame = self.myPage.mainFrame() 


if __name__ == "__main__": 
    app = QApplication([]) 
    producer = Producer() 
    webBrowser = Browser() 
    QThread.currentThread().setObjectName("MAIN") 
    producerThread = MyThread("producer") 
    producer.moveToThread(producerThread) 
    producerThread.started.connect(producer.Start) 
    producer.connect(producer, SIGNAL("jseval"), webBrowser.jseval) 
    webBrowser.show() 
    def aboutToQuit(): 
     producerThread.quit() 
     time.sleep(1) 
    qApp.aboutToQuit.connect(aboutToQuit) 
    time.sleep(.1) 
    producerThread.start() 
    sys.exit(app.exec_())