PDA

View Full Version : QWebElement available for QtScript, Marshaling/Template?



jasonknight
6th March 2010, 16:46
Hey All,

I have hit a little snag, and haven't been able to find exactly what I am looking for. I want to be able to grab html elements out of a webframe, manipulate them with QtScript, and put them back in. Maybe there is some way already to do this, but what I have found so far is that I have to register a metattype for QWebElement, which means creating a template to convert the QWebElement to a QScriptValue and back again.

The problem is, I am a bit away for knowing how to do this. I checked out the example code, but not sure I really follow it. I don't want just values, I want a calleable/malleable class that when I do something to it in qtscript, it reflects in the page. Am I reinventing the wheel? Aiming too high?

Here is the function that returns the QWebElement;

QWebElement MyWindow::getElementById(QString id) {
QWebElement e =_self->webView->page()->currentFrame()->findFirstElement(id);
return e;
}

in QtScript, I would like to be able to do this:



var elem = this.getElementById('#test'); // works, but throws the qRegisterMetaType error
elem.setInnerXml("<span class='someclass'>Yay, I worked!</span>");


I can imagine some ways to dance around this, like creating a slot called setHtmlOfElement(QString id, QString html) { ... }

If there is no simple way to wrap the QWebElement up for QTScript, I may just do that.

I am just wondering, is there a better way?

Thanks in advance for any help and pointers,
Jason

buus
7th March 2010, 13:32
I am not sure that this i what you are looking for but if it´s just manipulating JavaScript you could use something like.



JavaScript:

function updateHTML(elmId, value) {
document.getElementById(elmId).innerHTML = value;
}



Then call that code form Qt using evaluateJavaScript ( const QString & scriptSource )

vonhof
17th July 2012, 17:38
Even though this is a very old thread - I found myself needing to expose QWebElements from and to QtScripts and since there is no explanation as to how to do this (not that i've seen anyway) here's what i ended up doing:

Make a new wrapper class that extends QObject (also using the Q_OBJECT template etc.) like the example below. What it does is give you a QObject that you can expose to your QScriptEngine - which wraps the actual QWebElement. Expose as many methods as public slots as you need from the internal QWebElement to be able to manipulate it...

There are some of the conversion operators that i'm not 100% sure about (I'm no heavy C++ dev) but it seems to do the trick. The method implementations not present are as you'd expect... nothing fancy

class QWebElementWrapper : public QObject
{
Q_OBJECT
public:
QWebElementWrapper();
QWebElementWrapper(QWebElement *elm);
QWebElementWrapper(const QWebElement &elm);
QWebElementWrapper(const QWebElementWrapper &other);

QWebElementWrapper& operator =(const QWebElementWrapper &other) {
if (this != &other) {
this->_elm = other._elm;
}
return *this;
}

QWebElementWrapper& operator =(const QWebElement &other) {
this->_elm = new QWebElement(other);
return *this;
}

QWebElementWrapper& operator =(QWebElement* elm) {
this->_elm = elm;
return *this;
}

operator QWebElement *() {
return _elm;
}

operator QWebElement &() {
return *_elm;
}

operator const QWebElement&() const {
return *_elm;
}

bool isNull() {
return _elm == 0
|| _elm->isNull();
}


QWebElement *elm() {
return _elm;
}

static QScriptValue toScriptValue(QScriptEngine *engine,const QWebElementWrapper &s) {
QWebElementWrapper* p = new QWebElementWrapper(s);
return engine->newQObject(p,QScriptEngine::AutoOwnership);
}

static void fromScriptValue(const QScriptValue &obj, QWebElementWrapper &s) {
QWebElementWrapper* qObj = (QWebElementWrapper*)obj.toQObject();
s._elm = qObj->_elm;
}
private:
QWebElement* _elm;

signals:

public slots:

};

Q_DECLARE_METATYPE(QWebElementWrapper)

And then before using it you simply do as follows:


QScriptEngine engine;
qScriptRegisterMetaType(&engine,QWebElementWrapper::toScriptValue,QWebEleme ntWrapper::fromScriptValue);