2016-08-06 4 views
0

Ich möchte den folgenden Code, um die Anfrage URL beginnend mit http://down.51en.com:88 während des Webladeprozesses erhalten, und dann andere Verarbeitung mit dem Antwortobjekt der URL. In meinem Programm, sobald targetUrl einen Wert zugewiesen ist, möchte ich die Funktion targetUrlGetter(url), um es an den Aufrufer zurückgeben, aber das Problem ist, dass QApplication::exec() tritt in die Main Event-Schleife so kann Code am Ende der targetUrlGetter() Funktion nach der Exec nicht ausführen() Anruf, damit die Funktion nicht zurückkehren kann, habe ich versucht mit qApp.quit() in interceptRequest(self, info), um die Anwendung zu verlassen, so dass targetUrlGetter(url) zurückgeben kann, aber die Funktion kann immer noch nicht zurück und das Programm stürzt sogar beim Beenden (getestet auf Win7 32bit) Wie kann ich also das targetUrl an das Anruferprogramm zurückgeben?Verwenden von QApplication :: exec() in einer Funktion oder Klasse

Die Schwierigkeiten hier sind, wie man die Qt-Ereignisschleife ohne Abbruch beendet und die Anforderungsurl zum Anrufer zurückbringt.

import sys 

from PyQt5.QtWidgets import * 
from PyQt5.QtWebEngineWidgets import * 
from PyQt5.QtWebEngineCore import * 
from PyQt5.QtCore import * 


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.page = parent 

    def interceptRequest(self, info): 
     if info.requestUrl().toString().startswith('http://down.51en.com:88'): 
      self.targetUrl = info.requestUrl().toString() 
      print('----------------------------------------------', self.targetUrl) 
      qApp.quit() 

      # self.page.load(QUrl('')) 


def targetUrlGetter(url=None): 
    app = QApplication(sys.argv) 
    page = QWebEnginePage() 
    globalSettings = page.settings().globalSettings() 
    globalSettings.setAttribute(
     QWebEngineSettings.PluginsEnabled, True) 
    globalSettings.setAttribute(
     QWebEngineSettings.AutoLoadImages, False) 
    profile = page.profile() 
    webEngineUrlRequestInterceptor = WebEngineUrlRequestInterceptor(page) 
    profile.setRequestInterceptor(webEngineUrlRequestInterceptor) 
    page.load(QUrl(url)) 
    # view = QWebEngineView() 
    # view.setPage(page) 
    # view.show() 
    app.exec_() 
    return webEngineUrlRequestInterceptor.targetUrl 


url = "http://www.51en.com/news/sci/everything-there-is-20160513.html" 
# url = "http://www.51en.com/news/sci/obese-dad-s-sperm-may-influence-offsprin.html" 
# url = "http://www.51en.com/news/sci/mars-surface-glass-could-hold-ancient-fo.html" 
targetUrl = targetUrlGetter(url) 
print(targetUrl) 
+0

Ich kann das nicht reproduzieren. Das Skript wird ohne Fehler ausgeführt und gibt die angeforderte URL wie erwartet aus. Ich sehe keinen Grund, warum 'exec()' "hängen" sollte. Sind Sie sicher, dass es keine Netzwerkprobleme gibt? – ekhumoro

+0

@ekhumoro Sorry für mein armes Englisch, siehe den aktualisierten Beitrag wieder! Wenn Sie den Exit-Absturz nicht sehen können, testen Sie den Code mehr als einmal unter Windows – iMath

+0

Ich kann nicht unter Windows testen. Das Skript funktioniert gut unter Linux. Sie müssen einige grundlegende Debugging durchführen, um zu sehen, wo das Skript fehlschlägt. Wird die Webseite korrekt geladen? Verwenden Sie das [loadFinished-Signal] (http://doc.qt.io/qt-5/qwebenginepage.html#loadFinished), um dies zu überprüfen. Wird 'interceptRequest' überhaupt aufgerufen, und wenn ja, wie lautet die Ausgabe von' print (repr (info.requestUrl(). ToString())) '? Wird die 'if' Aussage jemals zu 'True' ausgewertet? – ekhumoro

Antwort

-1

Sie sollten immer QApplication am Anfang des Programms initialisieren und immer die QApplication::exec Funktion am Ende des Programms aufrufen.

Eine andere Sache ist, dass QWebEngineUrlRequestInterceptor.interceptRequest eine Callback-Funktion ist, die asynchron aufgerufen wird. Da innerhalb der Callback-Funktion info.requestUrl().toString() aufgerufen wird, ist kein Weg zu return das Ergebnis es synchron.

import sys 

from PyQt5.QtWidgets import * 
from PyQt5.QtWebEngineWidgets import * 
from PyQt5.QtWebEngineCore import * 
from PyQt5.QtCore import * 


class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.page = parent 

    def interceptRequest(self, info): 
     if info.requestUrl().toString().startswith('http://down.51en.com:88'): 
      self.targetUrl = info.requestUrl().toString() 
      print('----------------------------------------------', self.targetUrl) 
      # Don't do thatDo you really want to exit the whole program? 
      # qApp.quit() 

      # Do something here, rather than return it. 
      # It must be run asynchronously 

      # self.page.load(QUrl('')) 


def targetUrlGetter(url=None): 
    page = QWebEnginePage() 
    globalSettings = page.settings().globalSettings() 
    globalSettings.setAttribute(
     QWebEngineSettings.PluginsEnabled, True) 
    globalSettings.setAttribute(
     QWebEngineSettings.AutoLoadImages, False) 
    profile = page.profile() 
    webEngineUrlRequestInterceptor = WebEngineUrlRequestInterceptor(page) 
    profile.setRequestInterceptor(webEngineUrlRequestInterceptor) 
    page.load(QUrl(url)) 
    # view = QWebEngineView() 
    # view.setPage(page) 
    # view.show() 

    # Don't return this. It cannot be called synchronously. It must be called asynchronously. 
    # return webEngineUrlRequestInterceptor.targetUrl 

app = QApplication(sys.argv) # always initialize QApplication at the beginning of the program 
url = "http://www.51en.com/news/sci/everything-there-is-20160513.html" 
# url = "http://www.51en.com/news/sci/obese-dad-s-sperm-may-influence-offsprin.html" 
# url = "http://www.51en.com/news/sci/mars-surface-glass-could-hold-ancient-fo.html" 
targetUrl = targetUrlGetter(url) 
print(targetUrl) 
app.exec_() # always call the QApplication::exec at the end of the program 
+0

Dies ist eine falsche Antwort – iMath

Verwandte Themen