miércoles, 23 de noviembre de 2011

Override "the script on this page appears to have a problem" message in Qt

Este mensaje aparece al ejecutar código JavaScript en una aplicación que utiliza QtWebKit.
El problema reside en que Qt realiza una llamada a la función
bool QWebPage::shouldInterruptJavaScript()en el caso de que la ejecución
 de un programa JavaScript tarde más de lo normal.
 
Una primera aproximación al problema me lleva a aquí pero eso obliga a reimplementar dicha función.
Por  ahora lo que he intentado es derivar una clase de QWebPage e implementar la función shouldInterruptJavaScript.
Si hago la llamada directamente a esta función, se invoca a la mía como era de esperar pero durante el 
funcionamiento normal, no se llama a este procedimiento por lo que hay algo en la herencia que debo
estar haciendo mal. Además, el funcionamiento normal del código javascript no me acaba de funcionar.
 
Curiosamente si llamo a la función  shouldInterruptJavaScript de la clase original, se invoca al mensaje
por defecto pero después tampoco funcionan correctamente los scripts a pesar de indicar que no debe
interrumpirse.
 
 
La función está definida en QWebPage.cpp
 
bool QWebPage::shouldInterruptJavaScript()
{
#ifdef QT_NO_MESSAGEBOX
return false;
#else
QWidget* parent = (d->client) ? d->client->ownerWidget() : 0;
return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No);
#endif
}
 a) Una posible pista sería definir QT_NO_MESSAGEBOX para que devolviera siempre false.
 
    #ifndef QMESSAGEBOX_H
    #define QMESSAGEBOX_H
    #endif
 
  Pero esto simplemente no funcionaría ya que se tiene en cuenta a la hora de compilar el código fuente y no es el caso 
 

  
 b) crear una clase derivada de QWebPaqge y sobrescribir la función ShouldInterruptJavaScript
http://developer.qt.nokia.com/forums/viewthread/1263  
 
Posibles fuentes: 
 
  • https://github.com/niteria/phantomjs/commit/bb2adcc986a0a624798610fbbbfb883d2b4a0c4c 
  •  https://lists.webkit.org/pipermail/webkit-qt/2011-April/001446.html
 
 
 

 
Se prueba con 
 
    page=new QWebPage; 
    ui->webView->setPage(page); 
 
en lugar de 
    page=ui->webView->page();                   //Puntero a la página 
 
pero no funciona tampoco. En este caso la página inicial ni siquiera se carga. 
 
 
 
 
Tenemos un código fuente de ejemplo aquí en el cual me baso para finalmente escribir mi propia clase derivada de QWebPage.
 
El fichero custompage.h quedaría así:
 
#include <QWebPage>
#include <QWebView>


class CustomPage : public QWebPage
{
    Q_OBJECT
public:
    CustomPage(QWebView *parent = 0);

signals:

public slots:
    bool shouldInterruptJavaScript();

}; 
 
 y el custompage.cpp así
 
#include "custompage.h"

CustomPage::CustomPage(QWebView *parent) : QWebPage(parent)
{    
    parent->setPage(this);
}

bool CustomPage::shouldInterruptJavaScript()
{
    return false;                                       
}

 
El problema es que esto no acaba de funcionar correctamente. Si bien es cierto que al crear el objeto utilizando mi clase
 
    CustomPage *mypage;
    mypage=new CustomPage(ui->webView);       
    frame=mypage->mainFrame();                

consigo que no aparezca el mensaje de error del script, ahora lo que ocurre es que cuando el 
script falla, deja de funcionar correctamente - es como si hubiéramos contestado que sí a la pregunta 
de si deseamos interrumpir el script-
 
Finalmente posteo este problema en los foros de Qt y mientras comento el caso -todavía sin resolver- 
me doy cuenta de que el problema está en que utilizo un bucle que hace que el procesador
consuma muchos recursos provocando que el script tarde más de lo normal en la ejecución. 
 
 
El post y el workaround está aquí: http://developer.qt.nokia.com/forums/viewthread/13921/ 
 
No obstante, esto no soluciona el tema de que no podamos sobrescribir el método ShouldInte....
por lo que sigo investigando. 
Comentarios
0 comentarios
Para Comentar Elige el Sistema de Comentario de tu Agrado:
Comentarios Comentarios Comentarios