qt qml与c++_qt c++ qml-程序员宅基地

技术标签: qt  开发语言  

QT Quick是QT提供的一种高级用户界面工具包,包含对QML完美支持.

Qt Quick 就是使用 QML 构建的一套类库。

在这里插入图片描述

Qml模块本身并没有涉及图形显示,所有的图形处理都由Qt Quick模块完成。
QMl是一种高效的开发UI 的语言。QML(Qt Meta-Object Language,Qt元对象语言)是一种声明式编程语言,并且它是Qt框架的一个组成部分。 

单纯创建QML项目

在这里插入图片描述

在这里插入图片描述

 创建Qt Quick项目

这个是结合qt quick 和qt qml,使用empty.结合了c++的语法

在这里插入图片描述

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}


import QtQuick 2.9
import QtQuick.Window 2.2

Window
{
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
}

quick 的组件

ApplicationWindow    对应QMainWindow,提供顶层应用程序窗口
MenuBar    对应QMenuBar,提供窗口顶部横向的菜单栏
StatusBar    对应QStatusBar,提供状态栏
ToolBar    对应QToolBar,提供工具栏,可以添加ToolButton和其它组件
Action    对应QAction,提供能够绑定到导航和视图的抽象的用户界面动作
ScrollView    对应QScrollView,提供滚动视图
SplitView    对应QSplitter,提供可拖动的分割视图布局
StackView    对应QStackedWidget,提供基于栈的层叠布局
TabView    对应QTabWidget,提供带有标签的基于栈的层叠布局
TableView    对应QTableWidget,提供带有滚动条、样式和表头的表格
Button    对应QPushButton,提供按钮组件
CheckBox    对应QCheckBox,提供复选框
ComboBox    对应QComboBox,提供下拉框
TabView    对应QTabWidget,提供带有标签的基于栈的层叠布局
GroupBox    对应QGroupBox,提供带有标题、边框的容器
Label    对应QLabel,提供标签组件
ProgressBar    对应QProgressBar,提供进度条组件
RadioButton    对应QRadioButton,提供单选按钮
Slider    对应QSlider,提供滑动组件
SpinBox    对应QSpinBox,提供微调组件
Switch    提供类似单选按钮的开关组件
TextArea    对应QTextEdit,提供能够显示多行文本的富文本编辑框
TextField    对应QTextLine,提供显示单行文本的纯文本编辑框
ToolButton    对应QToolButton,提供在工具栏上显示的工具按钮

例子

import QtQuick 2.9
import QtQuick.Window 2.2

Window
{
    id:root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Text {

              text: "Hello, World!"
              color: "red"
              font.bold: true
              x:300;y:300
              width: root.width/3; height: 200
              font.pixelSize: 20
          }
    Image {
        id: name
        source: "./res/font.png"
        x:100;y:100
        width: 50; height:50

    }
}

QML的元素

QML的元素分为可视化元素和非可视化元素,常用的可视化元素如下表所示:

基本元素

基本元素对象(item)

矩形元素对象(Rectangle)

文本元素(Text)

图像元素(Image)

鼠标区域元素(MouseArea)

输入元素

文本输入(TextInput)

焦点区域(FocusScope)

文本编辑器(TextEdit)

按键元素(Key)

布局元素

锚定位(Anchor)

布局元素

Row(行)

Column(列)

Grid(栅格)

Flow(流)

Repeater(重复元素)

 Item(基础元素对象)

是所有可视化元素的基础对象,其他可视化元素都继承于Item.它本身不会有任何绘制操作

Image(图像元素)

    Image {
        id: name
        source: "./res/font.png"
        x:100;y:100
        width: 50; height:50

    }

Text文本元素

    Text {

              text: "Hello, World!"
              color: "red"
              font.bold: true
              x:300;y:300
              width: root.width/3;height: 200
              font.pixelSize: 20
          }
MouseArea(鼠标区域)
 Rectangle {
     color: "yellow"
     width: 100; height: 100
     MouseArea {
         anchors.fill: parent
         onClicked: console.log("clicked yellow")  //onClicked 为响应函数 对应于
                                                    信号clicked(MouseEvent mouse)

     }
}

其他

var:可以引用任何数据类型的通用属性类型。

 Rectangle {
     color: "yellow"
     width: 100; height: 100
     property double number:1.2   //用于自定义变量,需要设置其类型
     property var aRect: Qt.rect(10, 10, 10, 10)

}

NumberAnimation 动画

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Rectangle {
          width: 100; height: 100
          color: "red"

          NumberAnimation on y { to: 500; duration: 4000 }
      }
}

元素的属性

对元素进行操作的时候需要了解元素的属性,共有属性主要如下表所示,在熟悉了属性列表之后就可以熟练的使用基本元素了。

Geometry(几何属性)

左上角的位置(x,y)

长度和宽度(height,width)

元素间的堆叠次序(z)

Layout handling(布局操作)

锚定关系(anchors)

水平和垂直居中

边距关系(margin)

Key handling(按键操作)

按键定位(keyNavigation)

附加按键(key)

输入焦点(focus)

Transformation(转换)

缩放和旋转(scale\rotate)

旋转基点(transformorigin)

通用x.y.z属性列表转换(transform)

Visual(可视化)

不透明度(opacity)

可见性(visible)

裁剪(clip)用来控制边界

平滑(smooth)用来提高渲染质量

State definition(状态定义)

提供了元素当前所支持的状态列表(state)

id:是每个元素的标识,每个元素的id属性是唯一。子元素可以通过访问parent的id关键字访问父元素。
列表属性

如果只有一个元素,“[]”可以省略

Item {
    id: itemroot
    children:
    [
        Text{
            text: "aa"
        },
        Button {
            x:50;y:30
            id:bt1
            text: "bt"
        }
    ]
}

分组属性

Item {
    id: itemroot   
    Text{
        text: "aa"
    }
    Button {
        x:50;y:30
        id:bt1
        text: "bt"
    }        
}

附加属性

Item {
    id: itemroot
    Text{
        text: "aa"
        focus: true
        Keys.onPressed:{                  //附加属性
        console.log("TEST")}
    }
}

qml定义函数 

使用关键字function,函数的参数类型不需要声明,它们默认是variant类型

        function slot1( b)
        {
            console.log("qml");
        }

qmlRegisterType 

作用:注册C++类,可以在qml文件中使用C++类

qmlRegisterType 是一个可以将C++实现的类在QML中调用的,连接C++和QML的一个工具。

int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)

第一个参数* uri指的是QML中import后的内容,相当于头文件名,第二个第三个参数分别是主次版本号,第四个指的是QML中类的名字(第四个QML的类名首字母一定要大写,要不然会报错)。

#include <QtQml>
qmlRegisterType<MySliderItem>("com.mycompany.qmlcomponents", 1, 0, "Slider");

在main.qml 中
import com.mycompany.qmlcomponents 1.0
Slider {
}

在qml中使用C++类和对象

Qt提供了两种在QML环境中使用C++对象的方式:

第一种:导出c++类到qml

在C++中实现一个类,注册为QML环境的一个类型,在QML环境中使用该类型创建对象;(导出C++类到QML)
实现C++类;
注册QML类型;
在QML中导入类型;
在QML中创建由C++导出的类型的实例并使用
第二种:导出c++类对象到qml

在C++中构造一个对象,将这个对象设置为QML的上下文属性,在QML环境中直接使用该属性;(导出C++对象到QML)

导出c++类到qml

步骤

1.定义可以导出的C++类

前提条件
要想将一个类或对象导出到QML中,下列的前提条件必须满足:

  • 从QObject或QObject的派生类继承;
  • 使用Q_OBJECT宏

用到的知识点

信号、槽

只要是信号或者槽,都可以在QML中访问,可以把C++对象的信号连接到QML中定义的方法上,也可以把QML对象的信号连接到C++对象的槽上,还可以直接调用C++对象的槽或信号。

在c++类调用emit 发射信号,在qml处理槽函数

a.在c++定义信号,发射信号

signals:
    void sig_colorChanged(const QColor& color);

   emit sig_colorChanged(m_currentColor);

b.在qml定义槽函数

c.关联信号和槽

第一种绑定办法:在qml中使用connections

        Connections {
            target: colorMaker;
            onSig_colorChanged: {
                colorRect.color = color;
            }
        }
  • 上例中Connections的target不显式设置时,parent默认为其qml中的父元素
  • 如果target显式设置,则parent为target属性对应的colorMaker。
  • 槽函数定义为on_信号(其中信号第一个字符为大写)

第二种办法:使用connect

在main.cpp中使用connect,注意需要connect的第一个参数为对象,所以设置通过单例模式生成一个静态类对象。

 // engine 加载完成后 load以后
    auto list = engine.rootObjects();
    auto window = list.first();
    QObject::connect(MyObject::getInstance(), SIGNAL(cppSig(int, QString)),
                     window, SLOT(qmlSlot(int, QString)));

第三种:组件加载完成执行关联

        function slot1(col)
        {
            colorRect.color = col;
        }
       Component.onCompleted: {
            colorMaker.onSig_colorChanged.connect(slot1);
        }

 在qml调用emit 发射信号,在c++类处理槽函数

a.在qml定义好信号

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    signal qmlSignalA
}

b.在c++类定义好槽函数

public slots:
    void slot_fromqml();

void ColorMaker::slot_fromqml()
{
    int a = 1;
}

c.绑定信号和槽

        Component.onCompleted: {
            root.onQmlSignalA.connect(colorMaker.slot_fromqml);
        }

 注意的细节:信号为on_信号(其中信号第一个字符为大写)

d.在qml发射信号,不需要使用emit 关键字

       Button {
            id: start;
            text: "start";
            anchors.left: parent.left;
            anchors.leftMargin: 4;
            anchors.bottom: parent.bottom;
            anchors.bottomMargin: 4;
            onClicked: {
                  root.qmlSignalA();
            }
        }

_ENUMS宏

要导出的类定义了想在QML使用的枚举类型,可以使用Q_ENUMS宏将该枚举类型注册到元对象系统中。

Q_INVOKABLE宏

定义一个类的成员函数时使用Q_INVOKABLE宏来修饰,就可以让该方法被元对象系统调用。
这个宏必须放在返回类型前面。

延伸:普通类成员函数是不能直接在qml使用。除非是声明为槽函数或者用Q_INVOKABLE声明函数

    Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);
public slots:
     void setcolor();

Q_PROPERTY宏

Q_PROPERTY宏用来定义可通过元对象系统访问的属性,通过它定义的属性,可以在QML中访问、修改,也可以在属性变化时发射特定的信号。

2.注册一个QML可用的类型

将C++类型注册为QML类型。在qml中也是一个类。可用下面的函数:

用qmlRegisterSingletonType()来注册一个单例类型;
qmlRegisterType()来注册一个非单例类型;
用qmlRegisiterTypeNotAvailable()来注册一个类型用来占位;
用qmlRegisterUncreatableType()来注册一个具有附加属性的附加类型

qmlRegisterType()是个模板函数,需要包含QQmlEngineQtQml头文件

template<typename T>
int qmlRegisterType(const char* uri, int versionMajor, int versionMinor, const char* qmlName);

template<typename T, int metaObjectRevision>
int qmlRegisterType(const char* uri, int versionMajor, int versionMinor, const char* qmlName);

 uri:指定一个唯一的包名,类似于Java中的那种,一是用来避免名字冲突,二是可以把多个相关类聚合到一个包中方便引用;则在qml文件中 需要import 这个包
//比如我们常写的“import QtQuick.Control 1.2”,其中的“QtQuick.Controls”就是包名uri
//1.2是版本,是versionMajor和versionMinor的组合;
//qmlName则是QML中可以使用的类名;
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "colormaker.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

注册动作一定要放在QML上下文创建之前,否则的话,没有用;

3.在QML中导入C++注册的类型

使用import语句,如

import an.qt.ColorMaker 1.0

4.在QML中创建C++导入类型的实例

完整例子

QT += quick
CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp \
    colormaker.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

HEADERS += \
    colormaker.h
#ifndef COLORMAKER_H
#define COLORMAKER_H

#include <QObject>
#include <QColor>

class ColorMaker : public QObject
{
    Q_OBJECT
    Q_ENUMS(GenerateAlgorithm)

    Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY sig_colorChanged);
    Q_PROPERTY(QColor timeColor READ timeColor);

public:
    explicit ColorMaker(QObject *parent = nullptr);
    ~ColorMaker();

    enum GenerateAlgorithm {
        RandomRGB,
        RandomRed,
        RandomGreen,
        RandomBlue,
        LinearIncrease
    };

    QColor getColor() const;
    void setColor(const QColor& color);
    QColor timeColor() const;

    Q_INVOKABLE GenerateAlgorithm algorithm() const;
    Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);

signals:
    void sig_colorChanged(const QColor& color);
    void sig_currentTime(const QString& strTime);

public slots:
    void slot_start();
    void slot_stop();
    void slot_fromqml();

protected:
    void timerEvent(QTimerEvent *event) override;

private:
    GenerateAlgorithm m_algorithm;
    QColor m_currentColor;
    int m_nColorTimer;
};

#endif // COLORMAKER_H

#include "colormaker.h"

#include <QTime>
#include <QTimerEvent>

ColorMaker::ColorMaker(QObject *parent)
    : QObject(parent)
    ,m_algorithm(RandomRGB)
    ,m_currentColor(Qt::black)
    ,m_nColorTimer(0)
{

}
ColorMaker::~ColorMaker()
{

}

QColor ColorMaker::getColor() const
{
    return m_currentColor;
}
void ColorMaker::setColor(const QColor& color)
{
    m_currentColor = color;
    emit sig_colorChanged(m_currentColor);
}
QColor ColorMaker::timeColor() const
{
    QTime time = QTime::currentTime();
    int r = time.hour();
    int g = time.minute()*2;
    int b = time.second()*4;

    return QColor::fromRgb(r,g,b);
}

ColorMaker::GenerateAlgorithm ColorMaker::algorithm() const
{
    return m_algorithm;
}
void ColorMaker::setAlgorithm(GenerateAlgorithm algorithm)
{
    m_algorithm = algorithm;
}

void ColorMaker::slot_start()
{
    if(m_nColorTimer == 0) {
        m_nColorTimer = startTimer(1000);
    }
}
void ColorMaker::slot_stop()
{
    if(m_nColorTimer > 0) {
        killTimer(m_nColorTimer);
        m_nColorTimer = 0;
    }
}

void ColorMaker::slot_fromqml()
{
    slot_start();
}

void ColorMaker::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == m_nColorTimer) {
        switch (m_algorithm) {
            case RandomRGB:
                m_currentColor.setRgb(qrand()%255,qrand()%255,qrand()%255);
                break;
            case RandomRed:
                m_currentColor.setRed(qrand()%255);
                break;
            case RandomGreen:
                m_currentColor.setGreen(qrand()%255);
                break;
            case RandomBlue:
                m_currentColor.setBlue(qrand()%255);
                break;
            case LinearIncrease:
                int r = m_currentColor.red() + 10;
                int g = m_currentColor.green() + 10;
                int b = m_currentColor.blue() + 10;
                m_currentColor.setRgb(r%255,g%255,b%255);
                break;
        }
        emit sig_colorChanged(m_currentColor);
        emit sig_currentTime(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
    }else {
        QObject::timerEvent(event);
    }
}
//#include <QGuiApplication>
//#include <QQmlApplicationEngine>

//int main(int argc, char *argv[])
//{
//    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

//    QGuiApplication app(argc, argv);

//    QQmlApplicationEngine engine;
//    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
//    if (engine.rootObjects().isEmpty())
//        return -1;

//    return app.exec();
//}

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "colormaker.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
//import QtQuick 2.9
//import QtQuick.Window 2.2

//Window {
//    visible: true
//    width: 640
//    height: 480
//    title: qsTr("Hello World")
//}



import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0

import an.qt.ColorMaker 1.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    signal qmlSignalA

    Rectangle {
        width: 360;
        height: 360;

        Text {
            id: timeLabel
            anchors.left: parent.left;
            anchors.leftMargin: 4;
            anchors.top: parent.top;
            anchors.topMargin: 4;
            font.pixelSize: 26;
        }

        ColorMaker {
            id: colorMaker;
            color: Qt.green;
        }

        Rectangle {
            id: colorRect;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            color: "blue";
        }

        Button {
            id: start;
            text: "start";
            anchors.left: parent.left;
            anchors.leftMargin: 4;
            anchors.bottom: parent.bottom;
            anchors.bottomMargin: 4;
            onClicked: {
                  root.qmlSignalA();
//                colorMaker.slot_start();
            }
        }

        Button {
            id: stop;
            text: "stop";
            anchors.left: start.right;
            anchors.leftMargin: 4;
            anchors.bottom: start.bottom;
            onClicked: {
                colorMaker.slot_stop();
            }
        }
        function slot1(col)
        {
            colorRect.color = col;

        }

        function changeAlgorithm(button, algorithm) {
            switch(algorithm) {
                case 0:
                    button.text = "RandomRGB";
                    break;
                case 1:
                    button.text = "RandomRed";
                    break;
                case 2:
                    button.text = "RandomGreen";
                    break;
                case 3:
                    button.text = "RandomBlue";
                    break;
                case 4:
                    button.text = "LinearIncrease";
                    break;
            }
        }

        Button {
            id: colorAlgorithm;
            text: "RandomRGB";
            anchors.left: stop.right;
            anchors.leftMargin: 4;
            anchors.bottom: start.bottom;
            onClicked: {
                var algorithm = (colorMaker.algorithm() + 1) % 5;
                changeAlgorithm(colorAlgorithm,algorithm);
                colorMaker.setAlgorithm(algorithm);
            }
        }

        Button {
            id: quit;
            text: "quit";
            anchors.left: colorAlgorithm.right;
            anchors.leftMargin: 4;
            anchors.bottom: start.bottom;
            onClicked: {
                Qt.quit();
            }
        }

        Component.onCompleted: {
            colorMaker.color = Qt.rgba(0,180,120,255);
            colorMaker.setAlgorithm(colorMaker.LinearIncrease);
            changeAlgorithm(colorAlgorithm,colorMaker.algorithm());
            colorMaker.onSig_colorChanged.connect(slot1);
            root.onQmlSignalA.connect(colorMaker.slot_fromqml);
        }

        Connections {
            target: colorMaker;
            onSig_currentTime: {
                timeLabel.text = strTime;
                timeLabel.color = colorMaker.timeColor;
            }
        }

//        Connections {
//            target: colorMaker;
//            onSig_colorChanged: {
//                colorRect.color = col;
//            }
//        }




    }

}

导出C++对象到QML

步骤

1.注册属性
要将一个对象注册为属性。

engine.rootContext()返回的是QQmlContext对象,QQmlContext类代表一个QML上下文,它的setContextProperty()方法可以为该上下文设置一个全局可见的属性;
注意:new出来的对象,QQmlContext只是使用,不会帮你删除,你需要自己找一个合适的时机来删除它;

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "colormaker.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    //qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("colorMaker", new ColorMaker);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

在QML中使用关联到C++对象的属性
一旦调用setContextProperty()导出了属性,就可以在QML中使用了,不需要import语句

在C++中使用QML对象

很多QML对象对应的类型,原本就是C++类型,比如Image对应QQuickImage,Text对应QQuickText等等。

Qt最核心的一个基础特性,就是元对象系统,通过元对象系统,你可以查询QObject的某个派生类的类名、有哪些信号、槽、属性、可调用的方法等信息,然后也可以使用QMetaObject::invokeMethod()调用QObject的某个注册到元对象系统中的方法。

而对于使用Q_PROPERTY定义的属性,可以使用QObject的property()方法访问属性,如果该属性定义了WRITE方法,还可以使用setProperty()修改属性。

所以,只要我们找到QML环境中的某个对象,就可以通过元对象系统来访问它的属性、信号、槽等。

1.在c++类中找到qml文档的根Item对象;

a.如果使用QQuickView+Item的程序结构方式,通过QQuickView的rootObject()直接就可以得到QML文档的根Item对象;

b.如果采用QQmlApplicationEngine+Window的程序结构方式,QML文档根对象的获取就麻烦些;示例中通过QQmlApplicationEngine的rootObjects()方法获取到engine加载QML后生成的所有顶层对象的列表,然后遍历、比较objectName,根据QML中设置的对象名字“rootObject”来找到正确的QML根对象;

2.查找qml一个对象

QObject定义了一个属性objectName,这个对象名字属性,就可以用于查找对象。查找对象的方法:findChild()和findChildren():

T QObject::findChild(const QString& name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

QList<T> QObject::findChildren(const QString& name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

QList<T> QObject::findChildren(const QRegExp& regExp, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

QList<T> QObject::findChildren(const QRegularExpression& re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

 3.使用元对象调用QML对象的方法

QMetaObject的invokeMethod()方法用来调用一个对象的信号、槽、可调用方法。它是个静态方法。

bool QMetaObjcet:invokeMethod(
						QObject* obj, 
						const char* member,
						Qt::ConnectionType type,
						QGenericReturnArgument ret,
						QGenericReturnArgument  vla0 = QGenericReturnArgument(0),
						QGenericReturnArgument  vla1 = QGenericReturnArgument(),
						QGenericReturnArgument  vla2 = QGenericReturnArgument(),
						QGenericReturnArgument  vla3 = QGenericReturnArgument(),
						QGenericReturnArgument  vla4 = QGenericReturnArgument(),
						QGenericReturnArgument  vla5 = QGenericReturnArgument(),
						QGenericReturnArgument  vla6 = QGenericReturnArgument(),
						QGenericReturnArgument  vla7 = QGenericReturnArgument(),
						QGenericReturnArgument  vla8 = QGenericReturnArgument(),
						QGenericReturnArgument  vla9 = QGenericReturnArgument());

返回值:返回true说明调用成功;返回false,要么是因为没有你说的那个方法,要么是参数类型不匹配;
obj:被调用对象的指针;
member:方法名字;
type:连接类型;invokeMethod为信号槽而生,你可以指定连接类型,如果被调用的对象和发起调用的线程是同一线程,那么可以使用Qt::DirectConnection、Qt::AutoConnection、Qt::QueuedConnection,如果被调用对象在另一个线程,那么建议使用Qt::QueuedConnection;
ret:接收返回值;
然后就是多达10个可以传递给被调用方法的参数;(看来信号槽的参数个数是有限制的,最好不要超过10个)
 

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    QObject* root = NULL;
     QList<QObject*> rootObjects = engine.rootObjects();
     int count = rootObjects.size();
     for(int i=0; i<count; ++i) {
         if(rootObjects.at(i)->objectName() == "rootObject") {
             root = rootObjects.at(i);
             break;
         }
     }
     
     QObject* startButton = root->findChild<QObject*>("startButton");
     startButton->setProperty("text","start");


    return app.exec();
}
Window {
    id: root;
    objectName: "rootObject";
    width: 400;
    height: 400;
    visible: true;

    signal qmlSignalA

        Button {
            id: start;
            objectName: "startButton";
            anchors.left: parent.left;
            anchors.leftMargin: 4;
            anchors.bottom: parent.bottom;
            anchors.bottomMargin: 4;
            onClicked: {

                colorMaker.setcolor();
            }
        }
}


 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baidu_16370559/article/details/127926437

智能推荐

软件测试流程包括哪些内容?测试方法有哪些?_测试过程管理中包含哪些过程-程序员宅基地

文章浏览阅读2.9k次,点赞8次,收藏14次。测试主要做什么?这完全都体现在测试流程中,同时测试流程是面试问题中出现频率最高的,这不仅是因为测试流程很重要,而是在面试过程中这短短的半小时到一个小时的时间,通过测试流程就可以判断出应聘者是否合适,故在测试流程中包含了测试工作的核心内容,例如需求分析,测试用例的设计,测试执行,缺陷等重要的过程。..._测试过程管理中包含哪些过程

政府数字化政务的人工智能与机器学习应用:如何提高政府工作效率-程序员宅基地

文章浏览阅读870次,点赞16次,收藏19次。1.背景介绍政府数字化政务是指政府利用数字技术、互联网、大数据、人工智能等新技术手段,对政府政务进行数字化改革,提高政府工作效率,提升政府服务质量的过程。随着人工智能(AI)和机器学习(ML)技术的快速发展,政府数字化政务中的人工智能与机器学习应用也逐渐成为政府改革的重要内容。政府数字化政务的人工智能与机器学习应用涉及多个领域,包括政策决策、政府服务、公共安全、社会治理等。在这些领域,人工...

ssm+mysql+微信小程序考研刷题平台_mysql刷题软件-程序员宅基地

文章浏览阅读219次,点赞2次,收藏4次。系统主要的用户为用户、管理员,他们的具体权限如下:用户:用户登录后可以对管理员上传的学习视频进行学习。用户可以选择题型进行练习。用户选择小程序提供的考研科目进行相关训练。用户可以进行水平测试,并且查看相关成绩用户可以进行错题集的整理管理员:管理员登录后可管理个人基本信息管理员登录后可管理个人基本信息管理员可以上传、发布考研的相关例题及其分析,并对题型进行管理管理员可以进行查看、搜索考研题目及错题情况。_mysql刷题软件

根据java代码描绘uml类图_Myeclipse8.5下JAVA代码导成UML类图-程序员宅基地

文章浏览阅读1.4k次。myelipse里有UML1和UML2两种方式,UML2功能更强大,但是两者生成过程差别不大1.建立Test工程,如下图,uml包存放uml类图package com.zz.domain;public class User {private int id;private String name;public int getId() {return id;}public void setId(int..._根据以下java代码画出类图

Flume自定义拦截器-程序员宅基地

文章浏览阅读174次。需求:一个topic包含很多个表信息,需要自动根据json字符串中的字段来写入到hive不同的表对应的路径中。发送到Kafka中的数据原本最外层原本没有pkDay和project,只有data和name。因为担心data里面会空值,所以根同事商量,让他们在最外层添加了project和pkDay字段。pkDay字段用于表的自动分区,proejct和name合起来用于自动拼接hive表的名称为 ..._flume拦截器自定义开发 kafka

java同时输入不同类型数据,Java Spring中同时访问多种不同数据库-程序员宅基地

文章浏览阅读380次。原标题:Java Spring中同时访问多种不同数据库 多样的工作要求,可以使用不同的工作方法,只要能获得结果,就不会徒劳。开发企业应用时我们常常遇到要同时访问多种不同数据库的问题,有时是必须把数据归档到某种数据仓库中,有时是要把数据变更推送到第三方数据库中。使用Spring框架时,使用单一数据库是非常容易的,但如果要同时访问多个数据库的话事件就变得复杂多了。本文以在Spring框架下开发一个Sp..._根据输入的不同连接不同的数据库

随便推点

EFT试验复位案例分析_eft电路图-程序员宅基地

文章浏览阅读3.6k次,点赞9次,收藏25次。本案例描述了晶振屏蔽以及开关电源变压器屏蔽对系统稳定工作的影响, 硬件设计时应考虑。_eft电路图

MR21更改价格_mr21 对于物料 zba89121 存在一个当前或未来标准价格-程序员宅基地

文章浏览阅读1.1k次。对于物料价格的更改,可以采取不同的手段:首先,我们来介绍MR21的方式。 需要说明的是,如果要对某一产品进行价格修改,必须满足的前提条件是: ■ 1、必须对价格生效的物料期间与对应会计期间进行开启; ■ 2、该产品在该物料期间未发生物料移动。执行MR21,例如更改物料1180051689的价格为20000元,系统提示“对于物料1180051689 存在一个当前或未来标准价格”,这是因为已经对该..._mr21 对于物料 zba89121 存在一个当前或未来标准价格

联想启天m420刷bios_联想启天M420台式机怎么装win7系统(完美解决usb)-程序员宅基地

文章浏览阅读7.4k次,点赞3次,收藏13次。[文章导读]联想启天M420是一款商用台式电脑,预装的是win10系统,用户还是喜欢win7系统,该台式机采用的intel 8代i5 8500CPU,在安装安装win7时有很多问题,在安装win7时要在BIOS中“关闭安全启动”和“开启兼容模式”,并且安装过程中usb不能使用,要采用联想win7新机型安装,且默认采用的uefi+gpt模式,要改成legacy+mbr引导,那么联想启天M420台式电..._启天m420刷bios

冗余数据一致性,到底如何保证?-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏9次。一,为什么要冗余数据互联网数据量很大的业务场景,往往数据库需要进行水平切分来降低单库数据量。水平切分会有一个patition key,通过patition key的查询能..._保证冗余性

java 打包插件-程序员宅基地

文章浏览阅读88次。是时候闭环Java应用了 原创 2016-08-16 张开涛 你曾经因为部署/上线而痛苦吗?你曾经因为要去运维那改配置而烦恼吗?在我接触过的一些部署/上线方式中,曾碰到过以下一些问题:1、程序代码和依赖都是人工上传到服务器,不是通过工具进行部署和发布;2、目录结构没有规范,jar启动时通过-classpath任意指定;3、fat jar,把程序代码、配置文件和依赖jar都打包到一个jar中,改配置..._那么需要把上面的defaultjavatyperesolver类打包到插件中

VS2015,Microsoft Visual Studio 2005,SourceInsight4.0使用经验,Visual AssistX番茄助手的安装与基本使用9_番茄助手颜色-程序员宅基地

文章浏览阅读909次。1.得下载一个番茄插件,按alt+g才可以有函数跳转功能。2.不安装番茄插件,按F12也可以有跳转功能。3.进公司的VS工程是D:\sync\build\win路径,.sln才是打开工程的方式,一个是VS2005打开的,一个是VS2013打开的。4.公司库里的线程接口,在CmThreadManager.h 里,这个里面是我们的线程库,可以直接拿来用。CreateUserTaskThre..._番茄助手颜色

推荐文章

热门文章

相关标签