Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Norad от Июль 09, 2014, 15:28



Название: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 09, 2014, 15:28
Всем доброго времени суток! Подскажите пожалуйста как справиться со следующей проблемой. Не могу обратиться из C++ кода к QML. На QML у меня написана картинка из нескольких прямоугольников. Требуется по программе менять их параметры.  QML отображаю в Qt приложении как виджет. Код программы ниже.
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QApplication>
#include <QtDeclarative/QDeclarativeView>
#include <QtCore/QUrl>
#include <QDeclarativeContext>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    void inslaider(int);

private:
    Ui::MainWindow *ui;
    QDeclarativeView *ua;

signals:
    void slmove(int);

};

#endif // MAINWINDOW_H
Код:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHBoxLayout>
#include <QProcess>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    //установка рисунка на слой виджета в интерфейсе
    ui->setupUi(this);
    ua = new QDeclarativeView;
    ua->setSource(QUrl("qrc:/tor.qml"));
    ua->setResizeMode(QDeclarativeView::SizeRootObjectToView);
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(ua);
    ui->widget->setLayout(layout);
    }

MainWindow::~MainWindow()
{
    delete ui;
    delete ua;
}
Код прямоугольников.
Код:
Rectangle{

        id: rect_lhzv
        objectName: "lverh"
        color: "red"
        x: 20
        y: 217
        width: 100
        height: 1
    }
    Rectangle{
        id: rect_lhzn
        objectName: "lniz"
        color: "red"
        x: 20
        y: 224
        width: 100
        height: 1
    }
objectName для обращения я задал. Читал несколько статей на хабре, но все как-то мутно да и старые версии Qt там используются. У меня 5.2(сейчас уже 5.3 есть). В этих статьях написано, что нужно шаманить с Q_PROPERTY, qmlRegisterType или rootObject(). Подскажите пожалуйста, что и в каком порядке нужно делать. Заранее спасибо за содержательные ответы!)


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: ViTech от Июль 10, 2014, 13:32
QDeclarativeView использовалось в Qt 4.8, в 5-ой версии лучше пользоваться QQuickView.

Простой пример, как добраться до объекта в *.qml по имени:
Код
C++ (Qt)
#include <QGuiApplication>
#include <QQuickView>
 
int main(int argc, char *argv[])
{
   QGuiApplication app(argc, argv);
 
   QQuickView view;
   view.setSource(QUrl::fromLocalFile("application.qml"));
   view.show();
 
   QObject *object = view.rootObject();
 
   QObject *rect = object->findChild<QObject*>("rect");
   if (rect)
       rect->setProperty("color", "red");
 
   return app.exec();
}

Подробности:
Interacting with QML Objects from C++ (http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html)
Integrating QML and C++ (http://qt-project.org/doc/qt-5/qtqml-cppintegration-topic.html)
Deploying QML Applications (http://qt-project.org/doc/qt-5/qtquick-deployment.html)


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 11, 2014, 14:32
На строку ругается компилятор. Пишет main.cpp:10: ошибка: cannot convert 'QQuickItem*' to 'QObject*' in initialization
     QObject *object = view.rootObject();
                                       ^
Хм, еще если  делать таким образом, то объект QQuickView не отобразить на виджете. ???


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: ViTech от Июль 13, 2014, 12:22
На строку ругается компилятор. Пишет main.cpp:10: ошибка: cannot convert 'QQuickItem*' to 'QObject*' in initialization
     QObject *object = view.rootObject();
                                       ^
Значит надо правильно выполнить конвертацию при инициализации :). И указать, какой компилятор так ругается.

Хм, еще если  делать таким образом, то объект QQuickView не отобразить на виджете. ???
Чтобы отобразить QQuickView на виджете можно воспользоваться методом QWidget::createWindowContainer(), примерно так:
Код
C++ (Qt)
   view = new QQuickView();
   view_container = createWindowContainer( view, widget );
   widget->layout()->addWidget( view_container );
 


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 14, 2014, 08:56
На строку ругается компилятор. Пишет main.cpp:10: ошибка: cannot convert 'QQuickItem*' to 'QObject*' in initialization
     QObject *object = view.rootObject();
                                       ^
Значит надо правильно выполнить конвертацию при инициализации :). И указать, какой компилятор так ругается.

Хм, еще если  делать таким образом, то объект QQuickView не отобразить на виджете. ???
Чтобы отобразить QQuickView на виджете можно воспользоваться методом QWidget::createWindowContainer(), примерно так:
Код
C++ (Qt)
   view = new QQuickView();
   view_container = createWindowContainer( view, widget );
   widget->layout()->addWidget( view_container );
 

Скажите, какую версию Qt вы используете(у меня 5.3)? Создаю проект, чтобы проверить код, а он мне qml подключает через
Код:
QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
Компилятор у меня MinGW.


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 14, 2014, 09:39
Спасибо,  с созданием контейнера и его отображением разобрался) Точнее немного погуглил http://blog.qt.digia.com/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/
Код:
ui->setupUi(this);
    QQuickView *view = new QQuickView;
    view->setSource(QUrl("qrc:/main.qml"));
    QWidget *container = QWidget::createWindowContainer(view);
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(container);
    ui->widget->setLayout(layout);
Теперь буду пробовать обращаться из c++ к QML


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 14, 2014, 10:14
Проблема с cannot convert 'QQuickItem*' to 'QObject*' in initialization осталась. Все таки можно ли как-нибудь передавать в QML из C++ значения переменных. Делается ли это только через rootobject?


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: ViTech от Июль 14, 2014, 12:40
У меня тоже Qt 5.3, но компилятор сейчас msvc2012, он на такое не ругается :).

Проблема с cannot convert 'QQuickItem*' to 'QObject*' in initialization осталась.
Попробуйте указать явное преобразование:
Код
C++ (Qt)
QObject *object = static_cast<QObject *> (view.rootObject());

Все таки можно ли как-нибудь передавать в QML из C++ значения переменных. Делается ли это только через rootobject?
Это повод для самостоятельного глубокого изучения QQmlEngine, QQmlComponent, QQuickItem и т.п. :).


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 14, 2014, 15:16
Какой-то бред получается. Нафиг этот QML нужен, если в него из C++ данные через какую-то жопу(извиняюсь, накипело) передавать нужно. Сидел изучал гайды на английском, на хабре статейки. Понял, что можно свойства класса в QML передавать через Q_Property. Сигналы я так понял он видит автоматически из объектов декларированного в него класса. Даже синтаксис обработчика подсвечивает, когда пишу "onSignal:" Модуль импортирует, объявление класса внутри QML кода переваривает. Но как только запускаю сборку, он мне говорит, что типа такого сигнала нет!!!! так спрашивается, какого черта ты мне подсвечивал код обработчика сигнала????!!!!! >:( Тут на целом форуме нет разве людей, кто может в этот странный QML свойство объекта передать? Для такой казалось бы простетской операции приходится уже который день бродить по сайтам...


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: ViTech от Июль 14, 2014, 15:53
Не всё сразу :). Выкладывайте или здесь пример проекта в архиве, или на GitHab`е каком, чтобы люди могли быстро его себе поставить, собрать, исправить что надо. Указывайте места, где что-то не получается, чтобы разговор предметным был. Люди, которые могут передать свойство в QML, конечно, есть, и это не сложная операция. Почему не получается конкретно у Вас, нужно разбираться в частном порядке.


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 15, 2014, 11:00
Нашел решение, как передать значение переменной.
Код:
view->rootContext()->setContextProperty("rv",VAL);
    view->setSource(QUrl("qrc:/main.qml"));
,
где rv - переменная в QML файле, VAL - переменная в объекте класса MainWindow. Значение этой переменной передается только при компиляции. На последующие изменения данной переменной QML никак не реагирует. Вот собственно создал проект. Форма дизайнера, на ней виджет, в виджете я отобразил QML файл. С помощью вертикального слайдера изменяю значение переменной VAL.
Объявил даже эту переменную через Q_PROPERTY(int VAL READ getVAL WRITE setVAL NOTIFY VALChanged). В документации написано, что NOTIFY оповещает QML движок об изменении значения переменной, но что-то я похоже делаю не так. Залил проект на rghost. Вот собственно он: http://rghost.ru/56900478 Взгляните пожалуйста, буду очень благодарен за подсказку, что я сделал не так.


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 15, 2014, 11:16
Собственно залил еще и на github https://gist.github.com/Norad2142/8a1f893760cee41ba7df

Только странно этот ресурс работает, уже не может найти мой гист


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: ViTech от Июль 15, 2014, 15:26
Нашел решение, как передать значение переменной.
...
где rv - переменная в QML файле, VAL - переменная в объекте класса MainWindow. Значение этой переменной передается только при компиляции. На последующие изменения данной переменной QML никак не реагирует. Вот собственно создал проект. Форма дизайнера, на ней виджет, в виджете я отобразил QML файл. С помощью вертикального слайдера изменяю значение переменной VAL.
Объявил даже эту переменную через Q_PROPERTY(int VAL READ getVAL WRITE setVAL NOTIFY VALChanged). В документации написано, что NOTIFY оповещает QML движок об изменении значения переменной, но что-то я похоже делаю не так. Залил проект на rghost. Вот собственно он: http://rghost.ru/56900478 Взгляните пожалуйста, буду очень благодарен за подсказку, что я сделал не так.

Свойство VAL, объявленное в MainWindow, ни коим образом не относится к коду в QML, потому что объект типа MainWindow в файле QML не присутствует :). Если надо, чтобы объект С++ со своими свойствами и событиями можно было вставить в QML, нужно делать примерно так: http://rghost.ru/56904788.


Название: Re: Qt+QML Проблема с обращением из C++ к коду QML
Отправлено: Norad от Июль 17, 2014, 10:23
Большое Вам спасибо! Вчера разобрался во всем, смог закончить свою программу :D