【问题标题】:Qt Signals and Slots - nothing happensQt 信号和插槽 - 没有任何反应
【发布时间】:2014-05-01 13:33:39
【问题描述】:

我目前正在尝试将 QML 信号连接到 C++ 插槽,但未成功。

我刚刚看了几个其他的例子,但我想我不知道如何获取 qml 文档的根对象...

我的问题是,似乎信号将从 qml 文件发送,但未在 cpp 文件中接收。执行此代码时没有错误。

//Counter.h
#ifndef COUNTER_H
#define COUNTER_H

#include <QObject>

class Counter : public QObject
{
    Q_OBJECT

private:
    int counter;

public:
    explicit Counter(QObject *parent = 0);

signals:
    void counterHasChanged(int);

public slots:
    void click();
};

#endif // COUNTER_H


//counter.cpp
#include "counter.h"
#include <QDebug>

Counter::Counter(QObject *parent) :
    QObject(parent)
{
    this->counter = 0;

    qDebug() << "Class Counter created";
}

void Counter::click() {
    this->counter++;

    qDebug() << "clickRegistered() - emit counterHasChanged()";

    emit counterHasChanged(counter);
}



//main.cpp
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "counter.h"
#include <QObject>
#include <QtQuick>
#include <QDebug>
#include <QQuickItem>
#include <QQmlContext>
#include <QtCore>

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

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/StatesTest2/main.qml"));
    viewer.showExpanded();

    QQuickView view;
    view.setSource(QUrl::fromLocalFile("qml/StatesTest2/main.qml"));

    QObject *item = view.rootObject();

    Counter counter;

    QObject::connect(item, SIGNAL(click()), &counter, SLOT(click()));

    return app.exec();
}



//main.qml
import QtQuick 2.0

Rectangle {
    id: root
    width: 360
    height: 360

    signal click

    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }

    MouseArea {

        anchors.fill: parent
        onClicked: {
            root.click
            console.log("click() qml")
        }
    }

    Text {
        text: "clicks: "
        x: 30
        y: 250
    }

    Text {
        id: counter
        text: "0"
        x: 75
        y: 250
    }
}

我知道有很多这样的话题.. 出于某种原因,没有其他解决方案对我有用..也许我应该改变我的 IDE :D

【问题讨论】:

    标签: c++ qt signals slots


    【解决方案1】:

    QQuickView::rootObject() 会返回一个QQuickItem,它显然在 Qt5.0 上没有任何 click 信号 (http://qt-project.org/doc/qt-5.0/qtquick/qquickitem.html)

    确保您将正确的(现有)信号链接到正确的插槽并且该信号被实际调用。

    【讨论】:

    • 我想添加自己的信号以将其发送到 cpp 文件。 QQuickItem 不可能吗?
    • Qt 应该向您的输出窗口/调试控制台打印一条消息,如果失败,QObject::connect() 将返回 false ...
    • @Zaiborg: if ( QObject:: ... ) is true 我只是想测试与 Connection::operator 的连接。如果连接成功,似乎这也应该是正确的。
    • @user3411048 如果你想添加你自己的信号,你应该子类化控件(如果它打算被子类化,但你可以很容易地通过构造函数的权限找到)。如果您从头开始编译 Qt,我 100% 不鼓励您更改源代码。
    • 我的代码和这个有什么区别:Connecting to QML Signals??
    【解决方案2】:

    我建议您将计数器添加为上下文属性。这需要进行以下更改。

    //Counter.h
    #ifndef COUNTER_H
    #define COUNTER_H
    
    #include <QObject>
    
    class Counter : public QObject
    {
        Q_OBJECT
    
    private:
        int counter;
    
    public:
        explicit Counter(QObject *parent = 0);
    
    signals:
        void counterHasChanged(int Value);
    
    public slots:
        void click();
    };
    
    #endif // COUNTER_H
    

    Counter.cpp 文件

    //counter.cpp
    #include "counter.h"
    #include <QDebug>
    
    Counter::Counter(QObject *parent) :
        QObject(parent)
    {
        this->counter = 0;
    
        qDebug() << "Class Counter created";
    }
    
    void Counter::click() {
        this->counter++;
    
        qDebug() << "clickRegistered() - emit counterHasChanged()";
    
        emit counterHasChanged(counter);
    }
    

    main.cpp 文件

       //main.cpp
    #include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include "counter.h"
    #include <QObject>
    #include <QtQuick>
    #include <QDebug>
    #include <QQuickItem>
    #include <QQmlContext>
    #include <QtCore>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        Counter counter;
        QtQuick2ApplicationViewer viewer;
        viewer.rootContext()->setContextProperty("counterObj",&counter);
    
        viewer.setMainQmlFile(QStringLiteral("qml/SO_QMLCPPCommunication/main.qml"));
    
    
        viewer.showExpanded();
    
        return app.exec();
    }
    

    并且在qml文件中,可以通过引用counterObj来访问Counter对象的slot。

      //main.qml
    import QtQuick 2.0
    
    Rectangle {
        id: root
        width: 360
        height: 360
    
        signal click
    
        Text {
            text: qsTr("Hello World")
            anchors.centerIn: parent
        }
    
        MouseArea {
    
            anchors.fill: parent
            onClicked: {
                counterObj.click()
                console.log("click() qml")
            }
        }
    
    Text {
        text: "clicks: "
        x: 30
        y: 250
    }
    
    Text {
        id: counter
        text: "0"
        x: 75
        y: 250
    }
    Connections
    {
        id:cppConnection
        target:counterObj
        ignoreUnknownSignals : true
        onCounterHasChanged:{
              //To access signal parameter,please name the parameter.
              console.debug("Counter value changed")
              counter.text = Value
       }
    }
    
    }
    

    【讨论】:

    • 这对我很有效!还有一个问题。如果我使用此解决方案,如何将信号从 c++ 发送回 qml?例如: MouseArea 被点击,areaClicked() 向 c++ 发出信号。然后我想增加计数器的值,并希望将信号“counterValueChanged()”发送回 qml 以更新 textField 或其他内容。
    • 您需要使用 QML Connections 组件来实现目标为 counterObj。然后你可以处理来自 Counter... Brief sn-p Connections{target:counterObj;onCounterValueChanged:{//do your stuff here.}} 的信号。
    • 如果我想执行代码,我会收到错误“unkown counterObj property [...]”。也许我必须在我的头文件中用“Q_PROPERTY(...NOTIFY...)”解决它? (?) 另一个问题.. 如果我使用 Connections 类,我还需要 QObject::connect 方法吗?我认为文档Connections 对初学者来说是可怕的。那个文件对我没有帮助......
    • 对于延迟回复,我深表歉意。我的互联网连接有一些问题。我已经编辑了我的答案并发布了整个源代码。当我在我的系统中测试它时效果很好。
    • 效果很好!附加说明:我在 cmets 中写道,我收到一个错误“ReferenceError:counterObj 未定义”。我刚刚得到这个是因为在我的 main.qml 中,viewer.rootContext()-&gt;setContextProperty("counterObj",&amp;counter); 行是在 viewer.setMainQmlFile(QStringLiteral("qml/ProjektName/main.qml")); 之后执行的
    猜你喜欢
    • 1970-01-01
    • 2012-10-15
    • 2015-07-18
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多