2009-08-19 14 views
13

Ambos QWebFrame y QWebPage tienen void loadFinished(bool ok) señal que se puede utilizar para detectar cuando una página web está completamente cargada. El problema es cuando una página web tiene contenido cargado asíncronamente (ajax). ¿Cómo saber cuándo la página está completamente cargada en este caso?¿Cómo saber cuando una página web se carga cuando se utiliza QtWebKit?

+0

¿Cómo se define la carga completa? ¿Hay una página completamente cargada cuando no se está ejecutando ningún código Ajax? (¿Incluso si el código ajax podría ejecutarse en el futuro?) ¿Hay una página completamente cargada cuando no se ejecutará código ajax en el futuro? ¿Qué harías diferente teniendo esta información? (¿Por qué es importante?) – Bill

+0

En mi caso, se llama a la llamada ajax en el evento 'onload'. Después de que haya terminado, pienso en una página completamente cargada. –

Respuesta

12

En realidad no he hecho esto, pero creo que se puede ser capaz de alcanzar su solución utilizando QNetworkAccessManager.

Puede obtener QNetworkAccessManager de su QWebPage utilizando la función networkAccessManager(). QNetworkAccessManager tiene una señal finished (QNetworkReply * reply) que se dispara cada vez que un archivo es solicitado por la instancia QWebPage.

La señal finished le proporciona una instancia de QNetworkReply, desde la cual puede obtener una copia de la solicitud original realizada, para identificar la solicitud.

Por lo tanto, crear una ranura para conectar a la señal finished, utilice el pasado-en los métodos de QNetworkReply de averiguar qué archivo acaba de terminar la descarga y si es su petición Ajax, hacer lo que el procesamiento que tiene que hacer.

Mi única advertencia es que nunca he hecho esto antes, así que no estoy 100% seguro de que funcione.

Otra alternativa podría ser utilizar los métodos de QWebFrame para insertar objetos en el modelo de objetos de la página y también insertar algunos JavaScript que luego notifiquen su objeto cuando se complete la solicitud de Ajax. Esta es una forma un poco más hackier de hacerlo, pero definitivamente debería funcionar.

EDIT:

La segunda opción me parece mejor. El flujo de trabajo es el siguiente:

Adjunte una ranura a la señal QWebFrame :: javascriptWindowObjectCleared(). En este punto, llame a QWebFrame :: evaluateJavascript() para agregar un código similar al siguiente: window.onload = function() {// la página se ha cargado por completo}

Escriba el código que necesite en esa función. Es posible que desee añadir un QObject a la página a través de QWebFrame :: addToJavaScriptWindowObject() y luego llamar a una función en ese objeto. Este código solo se ejecutará cuando la página esté completamente cargada.

Esperamos que esto responde a la pregunta!

+0

Tu forma de pensar es buena. Es lo que estoy haciendo ahora y ha estado funcionando hasta ahora. Ahora, tengo un problema porque llamo a alguna función js después de recibir la señal finished() y no tiene ningún efecto, aunque debería. Cuando llamo manualmente a la misma función js usando un botón en un formulario con una vista de mi página, funciona como debería: envía una publicación preguntando sobre datos adicionales. Supongo que esperar solo en la señal de terminada() de QNAM no es suficiente ya que después de recibir los datos QWebFrame tiene que modificar el DOM y quizás hacer otras cosas antes de que esté listo para manejar las llamadas de js. Por favor, actualice su respuesta para reflejar esto. –

+0

¿Puede darme más información acerca de lo que está tratando de lograr exactamente? Según tengo entendido, es esto: 1) Carga una página (mediante QWebView-> load() o algún otro método) 2) Cuando se ha recibido el contenido de la página (el HTML), QNAM dispara la señal terminada() 3) Cuando la página completa - incluyendo archivos JS, CSS e imágenes - ha terminado de cargarse, el objeto QWebPage dispara la señal loadFinished() 4) En algún momento posterior, se cargan datos extra a través de Ajax ¿Y quieres saber cuándo ha sucedido el # 4? Explique más y es posible que pueda responder su pregunta completamente. –

+0

anuncio 1. No exactamente. Estoy usando QWebFrame :: load ya que no necesito ninguna fase de renderizado. Actualmente, sin embargo, estoy ** usando ** QWebView :: setPage para ver cómo se ve la página, pero esto es solo para fines de depuración. anuncio 2. No estoy interesado en html solo, así que no uso esta señal aquí. ad 3. Sí. ad 4. Sí. El momento de esta llamada ajax está estrictamente definido; sucede en el momento en que el usuario hace clic en parte de una fila de datos. Aquí está mi problema. Llamo a la misma función js con evaluateJavaScript y no pasa nada; no se está enviando ninguna solicitud de red (estoy supervisando todas las solicitudes enviadas por QNAM). TBC –

1

Cuando termine de cargar su html/images/etc inicial, eso es todo. Se es completamente cargado. Este hecho no cambia si se decide utilizar un poco de javascript para obtener algunos datos adicionales, páginas vistas o lo que sea después del hecho.

Dicho esto, lo que sospecho que quiere hacer aquí es exponer un objeto/interfaz QtScript a su vista que puede invocar desde el script de su página, proporcionando efectivamente una "devolución de llamada" en C++ una vez que haya decidido (desde el script de la página) que has "cargado completamente".

Esperanza esto ayuda a darle una dirección a tratar ...

+0

Esa no es mi página, no puedo cambiar la secuencia de comandos que contiene, así que no puedo invocar mi secuencia de comandos/código. La llamada Ajax se activa al hacer clic en una fila de datos (estoy simulando estos clics programáticamente) y recupera datos adicionales. Necesito leer estos datos después de cargarlos, así que necesito saber cuándo se completó la carga. –

+0

Entonces, ¿está tratando de usar Qt para realizar algún tipo de scripts entre sitios? No creo que eso vaya a funcionar. La única idea que se te viene a la mente es que puedes mirar por los estados HTTP ellos mismos, que comenzarías a "ver" después del evento cargado. – Shaun

+0

¿Por qué crees que no va a funcionar? Con QtWebKit tiene acceso completo a DOM y JavaScript de la página e incluso puede llamar a su propio JavaScript. Usted tiene acceso completo a la capa de red también. ¿Qué necesitas más? ¿Para qué necesitas estados HTTP? Es algo de muy bajo nivel. Todo lo que quiero y necesito es poder simular las acciones del usuario en el mismo entorno que el usuario tiene durante su navegación normal. ¿Cuál de las características necesito para esto, no tiene QtWebKit en su opinión? –

1

Para verificar la carga del elemento específico, puede usar QTimer.Algo como esto en Python:

@pyqtSlot() 
def on_webView_loadFinished(self): 
    self.tObject = QTimer() 
    self.tObject.setInterval(1000) 
    self.tObject.setSingleShot(True) 
    self.tObject.timeout.connect(self.on_tObject_timeout) 
    self.tObject.start() 

@pyqtSlot() 
def on_tObject_timeout(self): 
    dElement = self.webView.page().currentFrame().documentElement() 
    element = dElement.findFirst("css selector") 
    if element.isNull(): 
     self.tObject.start() 

    else: 
     print "Page loaded" 
0

El PO pensaron que era debido a las peticiones AJAX retraso pero también podría ser otra de las razones que explica también por qué una demora breve periodo de tiempo muy soluciona el problema. Hay un error que hace que el comportamiento descrito:

https://bugreports.qt-project.org/browse/QTBUG-37377

Para evitar este problema la señal loadingFinished() deben conectarse con cola conexión.

+0

Si mal no recuerdo, en mi caso el problema ** fue ** debido a que la llamada Ajax se realizó justo después de que se cargó la página. Sin embargo, como no sabemos qué se ha garantizado que se haya completado antes de que se emita la señal 'loadFinished()', la única solución robusta es usar 'window.onload' como lo sugiere Rob Knight. De todos modos, como el desarrollo de QtWebKit se descarta en favor de QtWebEngine, no contaría con ningún cambio. –

+0

Estoy de acuerdo. Esto ya no será arreglado. Pero la solución podría ser útil. Edité mi publicación diciendo que esta es otra posible razón para los síntomas dados. – Silicomancer

Cuestiones relacionadas