Russian Qt Forum
Ноябрь 23, 2024, 08:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt+QML Проблема с обращением из C++ к коду QML  (Прочитано 12115 раз)
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(). Подскажите пожалуйста, что и в каком порядке нужно делать. Заранее спасибо за содержательные ответы!)
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #1 : Июль 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++
Integrating QML and C++
Deploying QML Applications
Записан

Пока сам не сделаешь...
Norad
Гость
« Ответ #2 : Июль 11, 2014, 14:32 »

На строку ругается компилятор. Пишет main.cpp:10: ошибка: cannot convert 'QQuickItem*' to 'QObject*' in initialization
     QObject *object = view.rootObject();
                                       ^
Хм, еще если  делать таким образом, то объект QQuickView не отобразить на виджете. Непонимающий
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #3 : Июль 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 );
 
Записан

Пока сам не сделаешь...
Norad
Гость
« Ответ #4 : Июль 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.
Записан
Norad
Гость
« Ответ #5 : Июль 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
Записан
Norad
Гость
« Ответ #6 : Июль 14, 2014, 10:14 »

Проблема с cannot convert 'QQuickItem*' to 'QObject*' in initialization осталась. Все таки можно ли как-нибудь передавать в QML из C++ значения переменных. Делается ли это только через rootobject?
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #7 : Июль 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 и т.п. Улыбающийся.
Записан

Пока сам не сделаешь...
Norad
Гость
« Ответ #8 : Июль 14, 2014, 15:16 »

Какой-то бред получается. Нафиг этот QML нужен, если в него из C++ данные через какую-то жопу(извиняюсь, накипело) передавать нужно. Сидел изучал гайды на английском, на хабре статейки. Понял, что можно свойства класса в QML передавать через Q_Property. Сигналы я так понял он видит автоматически из объектов декларированного в него класса. Даже синтаксис обработчика подсвечивает, когда пишу "onSignal:" Модуль импортирует, объявление класса внутри QML кода переваривает. Но как только запускаю сборку, он мне говорит, что типа такого сигнала нет!!!! так спрашивается, какого черта ты мне подсвечивал код обработчика сигнала?Непонимающий!!!!! Злой Тут на целом форуме нет разве людей, кто может в этот странный QML свойство объекта передать? Для такой казалось бы простетской операции приходится уже который день бродить по сайтам...
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #9 : Июль 14, 2014, 15:53 »

Не всё сразу Улыбающийся. Выкладывайте или здесь пример проекта в архиве, или на GitHab`е каком, чтобы люди могли быстро его себе поставить, собрать, исправить что надо. Указывайте места, где что-то не получается, чтобы разговор предметным был. Люди, которые могут передать свойство в QML, конечно, есть, и это не сложная операция. Почему не получается конкретно у Вас, нужно разбираться в частном порядке.
Записан

Пока сам не сделаешь...
Norad
Гость
« Ответ #10 : Июль 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 Взгляните пожалуйста, буду очень благодарен за подсказку, что я сделал не так.
Записан
Norad
Гость
« Ответ #11 : Июль 15, 2014, 11:16 »

Собственно залил еще и на github https://gist.github.com/Norad2142/8a1f893760cee41ba7df

Только странно этот ресурс работает, уже не может найти мой гист
« Последнее редактирование: Июль 15, 2014, 12:11 от Norad » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #12 : Июль 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.
Записан

Пока сам не сделаешь...
Norad
Гость
« Ответ #13 : Июль 17, 2014, 10:23 »

Большое Вам спасибо! Вчера разобрался во всем, смог закончить свою программу Веселый
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.272 секунд. Запросов: 23.