QML in Maya

QML in Maya Техника

Пишу программу в Qt и возникла такая проблема, не понимаю как мне в C++ изменять значение переменных которые в qml были созданы. У меня есть C++ класс в котором есть кнопка которая вызывается из qml и в нее передаются определенные данные из qml а как мне в этой кнопке получать доступ к другим переменным и менять их?

Вот кнопка в C++:

#include "program.h"
#include <QQuickItem>
#include <QQuickView>
#include <QQmlProperty>


void program:: buttonClicked(int amount, int group, QString currency,bool type) {
qDebug() <<type;

Operations mid;
mid.setType(type);
mid.setGroup(group);
mid.setAmount(amount);
mid.setCurrency(currency);

operations.push_back(mid);

QObject* listViewer = viewer->findChild<QObject*>("theList");
QObject* listViewer2 = viewer->findChild<QObject*>("button2Invoke");



//Пробовал вот так:

QQuickView view;
view.setSource(QUrl::fromLocalFile("../moneyControl/main.qml"));
view.show();
QObject *object = view.rootObject();
QQmlProperty p(object, "currency");
qDebug()<<p.read();
//Но получаю ошибку:
//QQuickView does not support using windows as a root item. 

//If you wish to create your root window from QML, consider using QQmlApplicationEngine instead. 
}

Есть какой то способ сделать это так же просто как и получать всякие кнопки и лейблы из qml? по типу:

Object* listViewer = viewer->findChild<QObject*>("theList");

import QtQuick 2.15
import QtQuick.Window 2.2
import QtQuick.Controls 2.15
Window {
    width: 100
    height: 100
    title: "hello"
    Button {
        width: 600
        height: 600
        text: "mybtn"
        objectName: "btn"
    }
} , 

I launch this via python with

app = QGuiApplication([])
engine = QQmlApplicationEngine()
engine.load(QUrl.fromLocalFile("main.qml"))
app.exec_()

If I try to test this via,

import pytest
@pytest.fixture()
def window(qtbot):
    engine = QQmlApplicationEngine()
    engine.load(QUrl("main.qml"))
    window = engine.rootObjects()[0]  # this gives a QWindow object
    # qtbot.add_widget(window)  # this fails due not being QWidget
    # window.show()
    yield window

def test_window_title(window):
    assert window.title() == "hello"

this test will pass, but probably by commenting out add_widget I will most likely stumble upon other issues If I persist. However if I try loading my QML via QQuickWidget as such:

view = QQuickWidget()
view.setSource(QUrl.fromLocalFile("main.qml"))

then I can do qbot.add_widget(view), but I get a warning

QtWarningMsg: QQuickWidget does not support using windows as a root item. 

If you wish to create your root window from QML, consider using QQmlApplicationEngine instead. `

My main questions are:

  • Is it possible to somehow use all of the functionality on this pytest-qt plugin while having a QML based app, via some «:hacks» or, is it ok to just try and test it without the qbot.add_widget(QWidget) even tho it says its highly recommended.
  • If not possible which atm I think its not, could anyone perhaps guide me into supporting that here, or tell me other ways in which I can test then my python Slots, Signals etc.
Дополнительно:  Миллионы iPhone, устройств Android и iOS не будут иметь доступа в интернет, когда Россия запустит сертификат dst root ca x3. как подойти к проблеме

In my use case, I use python for all backend and only QML for the frontend. Please let me know if this is in the wrong repo to ask, or if someone with way more experience has already solved this, or has any other suggestions 🙂

OS : Ubuntu 20.04
Qt: PySide2 5.15.2

Oh , and also the workaround on issue #251 , doesnt work for me as it says qt_api as AttributeError: '_QtApi' object has no attribute 'QApplication' .

In this post, I will discuss how to use QtQuick/QML for tools inside of Maya and whether it should be used in production. Spoiler alert: it shouldn’t.

qml_ui

or this useful example:

qml_ui2

or something more professional and useful such as Telegram.

There are many articles on the internet discussing the differences and history between QtQuick and QtWidgets so I won’t go over that in depth here. In a nutshell, QtQuick has typically been used to create mobile, touch-friendly interfaces with nice fluid animations. However, QtQuick2, introduced in Qt5, provided many significant improvements and allowed desktop apps to take advantage of the higher performance and modern features of QtQuick interfaces.

Maya and many other DCC packages began converting to Qt right before Qt5 was released. Since QtQuick1 was not a good solution for desktop applications, just about all DCC applications that use Qt use QtWidgets. Autodesk also ended up doing some custom development in Qt for bug fixes and behavioral adjustments to get Maya exactly how they wanted so they have a custom build that isn’t the same as what we would get if we installed Qt from the Qt site.

Obtaining the QML Modules

As a result of having a custom build and Maya not using any QtQuick, Maya does not ship with any of the QML modules such as Qt Quick Control and Qt Quick Particles. To get access to these modules, we have to get a version of Qt compatible with our version of Maya. Usually this consists of compiling Qt using the same compiler as Maya. For example on Windows, Maya 2018 and 2019 are compiled with Visual Studio 2015 and Maya 2020 is compiled with Visual Studio 2017. Luckily, for Maya 2020 on Windows, the Qt 5.12 that you download from the Qt site is compiled with Visual Studio 2017, so we can just grab files from that installation. If there is a version or compiler mismatch with what you download, you’ll need to compile Qt from source.

Expose the QML Modules to Maya

The QML modules are located in <QTDIR>/qml. We can tell QML in Maya to look in this directory by setting the QML2_IMPORT_PATH environment variable to point to this directory.

A runtime approach is to call QQmlEngine::addImportPath. Although I would typically use the runtime approach for modules included with specific interfaces you develop.

Create a Container Widget Owned By Maya

   
   
   

  
  
  



In Maya, we don’t need to create a QApplication so we may think we can just do something like:

  
  


Doing this will cause the interface window to flash briefly and then disappear. This is because we need the Maya main interface window to own this new window and QtWidget applications can only own QWidgets.

Maya is a QtWidget-based application. To use QtQuick interfaces inside a QtWidget application, we have two choices:

  1. Use QQuickWidget
  2. Use QQuickView or QQuickWindow mixed with QWidget::createWindowContainer

QQuickWidget has a minor performance hit so I’ll use QQuickView in this post. To display a QtQuick interface in a QtWidget application, we need to embed it inside a QWidget:

   

  
    A window that can be used to display a QML UI in Maya.

        
          
          
          
              
        
          
           
        
        
        
        

We create a container widget to hold the QQuickView and embed that widget into a QMainWindow. The window is parented to the main Maya window because we use the MayaQWidgetBaseMixin.

The *Focus* methods are to handle some focus issues I read about in a presentation from Telltale Games (RIP) Senior Tools Engineer, Michael Eads.

Дополнительно:  Юридические права Rot на планшет Samsung Galaxy Tab и юридические права Robo на смартфон от Samsung следующие

Removing ApplicationWindow

ApplicationWindow {
    id: window
    width: 1280
    height: 720
    visible: true

    ...
}
# Warning: root : QQuickView does not support using windows as a root item. 

If you wish to create your root window from QML, consider using QQmlApplicationEngine instead.

ApplicationWindow is processed by the QML engine to create a new window. However, we are already creating a window with QQuickView which is required to show the QtQuick interface in a QtWidget application. We can replace ApplicationWindow with another Container Control. I recommend using Page because it also supports a header and footer just like ApplicationWindow.

Sending Signals from QML to Python

To send Signals from the interface and respond to them in Python, we need to create a class derived from QObject that serves as the layer between the front and back end of the UI:

     

 
      

      
         
          

     
     
         

    
      
           
            
          
        

To tell QML about this class, we pass an instance into the QQmlContext of the QQmlEngine associated with our QQuickView:

  

        
          
          
        

       
         


 
       


  
   # Monkey patch to the window to prevent garbage collection
 

We can then use this property in our QML:

slider.onPositionChanged: backend.value = slider.valueAt(slider.position)

To download the sample code and some examples, check out my GitHub. The repo contains the QML modules for Maya 2020 on Windows, so if you install the Maya module in that repository, all the paths should be set up automatically and QML2_IMPORT_PATH will be set to the QML module directories within the repo.

Conclusion

Оцените статью
Master Hi-technology
Добавить комментарий