简体   繁体   English

QML / QtQuick和QWidget之间的双向连接

[英]Two way connection between QML/QtQuick and QWidget

I am trying to make an app that would use QSerialPort and QtQuick so I need to connect desktop-like app to QML somehow. 我正在尝试制作一个使用QSerialPort和QtQuick的应用程序,所以我需要以某种方式将类似桌面的应用程序连接到QML。 I managed to (ok i copied and made some changes) send information from QML to main.cpp but I can't send anything the other way. 我设法(好吧我复制并做了一些更改)从QML发送信息到main.cpp但我不能发送任何其他方式。 The wanted effect is to manage everything from .cpp, add and delete ListElements and send parameters to draw a graph. 想要的效果是管理.cpp中的所有内容,添加和删除ListElements以及发送参数以绘制图形。

main.cpp
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QQuickView view(QUrl::fromLocalFile("path/main.qml"));
    QObject *item = view.rootObject();
    MyClass myClass,mySecondClass;
    QObject::connect(item, SIGNAL(qmlSignal(QVariant)),
                     &myClass, SLOT(cppSlot(QVariant)));
    QObject::connect(&myClass, SIGNAL(Nazwa(QVariant)),
                     item, SLOT(onNazwa(QVariant)));
    QVariant c=200;
    emit myClass.Nazwa(c);

    view.show();
    return app.exec();
}

myclass.h myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QDebug>
#include <QQuickItem>
class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0);

signals:
    void Nazwa(QVariant a);

public slots:
    void cppSlot(const QVariant &v) {
       qDebug() << "QVariant :):" << v;

       QQuickItem *item =
           qobject_cast<QQuickItem*>(v.value<QObject*>());
       qDebug() << "Wymiary:" << item->width()
                << item->height();
    }

};

#endif // MYCLASS_H

main.qml main.qml

import QtQuick.Window 2.0
import QtQuick 2.0

Item {
    id: item
    width: 100; height: 100
//    Item{
//        id: item2
//        onNazwa: {    }
//    }
    signal qmlSignal(var anObject)
    MouseArea {
        anchors.fill: parent
        onClicked: {
            parent.width=200;
            item.qmlSignal(item)
        }
    }
}

Also any changes to main.qml would break the 1st connection and I don't even know why. 对main.qml的任何更改都会破坏第一个连接,我甚至不知道为什么。 Can You give me some advise or an example? 你能给我一些建议或一个例子吗? I spent 2nd day on Qt Documentation and I still can't do it :( 我在Qt文档上花了第二天,我仍然不能这样做:(

You can set a property on the qml and react to its change. 您可以在qml上设置属性并对其更改做出反应。

main.qml main.qml

Item {
    id: item
    property alias nazwa: item2.nazwa

    Item{
        id: item2
        property var nazwa: null
        onNazwaChanged: {} 
    }
}

and on main.cpp 并在main.cpp上

QQmlProperty::write(item, "nazwa", 10);

Alternatively you could invoke a method directly from c++ to qml. 或者,您可以直接从c ++调用方法到qml。

Everything is very well explained here 这里一切都很好解释

OK. 好。 I see what you want, but I recommend you to go through engine way. 我明白你想要什么,但我建议你通过引擎方式。 Try code below. 请尝试以下代码。 I used very simple example only to show how to, no more than. 我只使用非常简单的例子来展示如何,仅仅是。

MyClass .H: MyClass .H:

#include <QObject>
#include <QSerialPort>

class MyClass : public QObject
{
    Q_OBJECT
    QSerialPort *_port;
public:
    explicit MyClass(QObject *parent = 0);

signals:
    void sendData(const QString &data);

public slots:
    void startCom(const QString &name, int baud);
    void read();
    void writeData(const QByteArray &data = QByteArray("data"));
};

MyClass .CPP: MyClass .CPP:

MyClass::MyClass(QObject *parent) : QObject(parent)
{
}

void MyClass::startCom(const QString &name, int baud)
{
    _port = new QSerialPort(name, this);
    _port->setBaudRate(baud);
    if(_port->open(QIODevice::ReadWrite))
        connect(_port, &QSerialPort::readyRead, this, &MyClass::read);
    else
        emit sendData(tr("Error"));
}

void MyClass::read()
{
    emit sendData(QString::fromStdString(_port->readAll().toStdString()));
}

void MyClass::writeData(const QByteArray &data)
{
    _port->write(data);
}

main.cpp: main.cpp中:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    qmlRegisterType<MyClass>("com.some.myclass", 1, 0, "MyClass");
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

main.qml: main.qml:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import com.some.myclass 1.0

Window {
    id: root
    signal startPort(string name, int baud)
    width: 640
    height: 480
    ColumnLayout {
        id: colLay
        TextField {
            id: comName
            placeholderText: qsTr("COM-port name")
        }
        ComboBox {
            id: baud
            model: [ 9600, 19200, 115200 ]
        }
        Button {
            id: portBut
            text: qsTr("Start serial")
            onClicked: root.startPort(comName.text, baud.currentText)
        }
        Button {
            id: sendBut
            text: qsTr("Write data")
            onClicked: comClass.writeData
        }
        Label {
            id: dataLbl
            text: qsTr("No data")
        }
    }
    MyClass {
        id: comClass
        onSendData: dataLbl.text = data
    }

    onStartPort: comClass.startCom(name, baud)

    Component.onCompleted: root.show();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM