crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Массив QWebElement
id2606
  опции профиля:
сообщение 17.4.2013, 7:08
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 5.9.2012
Пользователь №: 3510

Спасибо сказали: 0 раз(а)




Репутация:   0  


В своем проекте я использую QWebPage.

Добавляю в него свой объект

m_scriptPage->mainFrame()->addToJavaScriptWindowObject("JSB", this);


в скрипте на странице вызываю функцию и указываю селектор например

    var e = JSB.findElements ("input");


Реализация

    QWebElement JSB::findElement (QString selector)
    {
        QWebElement doc = m_scriptPage->mainFrame()->documentElement ();
        return doc.findFirst();
    }


Если я ищу один элемент как в примере выше, то никаких проблем нет.
Но я никак не могу вернуть массив элементов!

если пытаюсь вернуть QWebElementCollection, то скрипт ругается что он не знает тип данных QWebElementCollection;
в QVariantList я не могу засунусь QWebElement.

Подскажите как мне вернуть массив элементов типа QWebElemnt и массив QObject* Так чтобы JavaScript на странице не ругался что он не знает что это такое.

Еще пытался вернуть другой свой объект типа

    class JSBElement : public QObject { ... }
    
    
    JSBElement JSB::getElement (QString selector)
    {
        QWebElement doc = m_scriptPage->mainFrame()->documentElement ();
        QWebElement e1 = doc.findFirst(selector);
    
        JSBElement e(e1);
        return e;
    }


JavaScript точно также ругался что не знает что такое JSBElement, но если вернуть JSBElement*, то все работает прекрасно.
Единственная проблема я не знаю когда мне можно удалять JSBElement.

    class JSBElement : public QObject { ... }
    
    
    QObject* JSB::getElement (QString selector)
    {
        QWebElement doc = m_scriptPage->mainFrame()->documentElement ();
        QWebElement e1 = doc.findFirst(selector);
    
        return new JSBElement (el);
    }


Вызовов функции из скрипта JSB.findElement может быть сколько угодно и работать скрипт может бесконечно, а значит память будет постоянно съедаться что недопустимо.

Подскажите как мне это все обойти и вообще в каком направлении рыть ? Вроде и вопрос простой, но не могу найти/сделать решение уже сутки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 17.4.2013, 10:59
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Чтобы засунуть в QVariant надо выполнить Q_DECLARE_METATYPE.
Чтобы свой кастомный объект, qScriptRegisterMetatype.
Про время жизни QObject читать тут http://qt-project.org/doc/qt-4.8/scripting...bject-ownership
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
id2606
  опции профиля:
сообщение 17.4.2013, 11:24
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 5.9.2012
Пользователь №: 3510

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 17.4.2013, 10:59) *
Чтобы засунуть в QVariant надо выполнить Q_DECLARE_METATYPE.
Чтобы свой кастомный объект, qScriptRegisterMetatype.
Про время жизни QObject читать тут http://qt-project.org/doc/qt-4.8/scripting...bject-ownership


Q_DECLARE_METATYPE (JSBElement) я конечно же сделал
А вот как заставить движек JavaScript видеть мой объект JSBElement не знаю.
Он на него всеравно ругается. А что бы зарегить его в пространстве ScriptEngine в JavaScript нужно сначала получить доступ к нему. А его нигде не дают. Другие пути еще не нашел. Сделал все через обертку.

Как засунуть свой объект в QVariantList я разобрался

Достаточно сделать так

QVariantList JSBPageObject::findElements(QString selector)
{
    QVariantList list;

    foreach (QWebElement e, m_webPage->findAllElements(selector))
        list.append(QVariant::fromValue(e));

    return list;
}



Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 17.4.2013, 11:53
Сообщение #4


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Объекты, наследуемые от QObject копировать нельзя.
Поэтому вот это:
QObject* JSB::getElement (QString selector)
    {
        QWebElement doc = m_scriptPage->mainFrame()->documentElement ();
        QWebElement e1 = doc.findFirst(selector);
    
        return new JSBElement (el);
    }

Правильное решение.
Для того чтобы объекты удалялись GC движка нужно выставить им Script Ownership.
Как сделать это, читайте здесь:
http://qt-project.org/doc/qt-4.8/scripting...bject-ownership
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
id2606
  опции профиля:
сообщение 17.4.2013, 13:20
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 5.9.2012
Пользователь №: 3510

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(lanz @ 17.4.2013, 11:53) *
Объекты, наследуемые от QObject копировать нельзя.
Поэтому вот это:
QObject* JSB::getElement (QString selector)
    {
        QWebElement doc = m_scriptPage->mainFrame()->documentElement ();
        QWebElement e1 = doc.findFirst(selector);
    
        return new JSBElement (el);
    }

Правильное решение.
Для того чтобы объекты удалялись GC движка нужно выставить им Script Ownership.
Как сделать это, читайте здесь:
http://qt-project.org/doc/qt-4.8/scripting...bject-ownership


Так я не могу понять где указывать Script Ownership
Я же не могу достучаться до QScriptEngine который находится в QWebFrame.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_lanz_*_*
сообщение 17.4.2013, 15:11
Сообщение #6





Гости








    


Цитата
Я же не могу достучаться до QScriptEngine который находится в QWebFrame.

И действительно :lol:
Цитата
In general its advised to use care when passing QObjects as arguments, as those objects don't become owned by the JavaScript engine; That means that the application developer has to be extra careful not to try to access QObjects that have already been deleted by the native environment.


Вопрос на засыпку. Почему не использовать JavaScript(document.getElement...) чтобы траверсить DOM?

Раскрывающийся текст
Не получается авторизоваться, прошу прощения :(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 1.4.2020, 7:15