QtQuick 应用程序和 C++ 插槽绑定错误

Posted

技术标签:

【中文标题】QtQuick 应用程序和 C++ 插槽绑定错误【英文标题】:QtQuick app and C++ slots binding error 【发布时间】:2015-04-16 06:21:45 【问题描述】:

我正在学习在后台使用 C++ 编写 QtQuick 应用程序。我的计划是尽可能多地用 QtQuick (QML) 编写代码,但是有一点我找不到,所以我决定使用 C++。基本上,我需要创建一个应用程序,为用户提供某些小部件和一个按钮。单击按钮后,将创建并调用 CLI 命令。我可以使用 javascript 创建这个 CLI 命令,但是我没有找到如何执行这个命令的方法,所以我决定使用 C++。

计划是在 QML 中的按钮上注册一个信号,并将该信号与 C++ 中的插槽连接。我打开了 QML 文档,在其中找到了几个有用的示例。我的测试应用代码包含两个源文件:

ma​​in.qml:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import "scripts.js" as Logic


ApplicationWindow 
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true
    minimumHeight: 480
    minimumWidth: 640


    ColumnLayout
        spacing: 2
        height: parent.height - 100
        width: parent.width

        GridLayout 
            id: grid
            columns: 3

            Label  text: "Vstupni soubor";  
            TextField 
                id: input_file_field
            
            Button 
                text: "..."
                onClicked: fileDialogInputFile.open()
            


            Label  text: "Vystupni adresar";  
            TextField id: output_dir_field
            Button 
                text: "..."
                onClicked: fileDialogOutputDir.open()
            

            CheckBox
                id: opt1
                text: "Volba 1"
            

            CheckBox
                id: opt2
                text: "Volba 2"
            

            CheckBox
                id: opt3
                text: "Volba 3"
            

        

        Button 

            signal qmlSignal(string msg)
            objectName: "myButton"

            text: "Analyzuj"
            onClicked: 
                qmlSignal("Hello from QML")
                console.log("Nahodne cislo " + Logic.func())
            
        

    


    TextArea 
        id: log_output
        width: parent.width
        height: 100
        y: parent.height - 100
        readOnly: true
        text: "Log zprav";
    

    FileDialog 
        id: fileDialogInputFile
        title: "Please choose a file"
        onAccepted: 
            input_file_field.text = fileDialogInputFile.fileUrl
        
    

    FileDialog 
        id: fileDialogOutputDir
        title: "Please select output directory"
        selectFolder: true
        onAccepted: 
            output_dir_field.text = fileDialogOutputDir.fileUrl
            console.log("You chose: " + fileDialogOutputDir.fileUrl)
        
    



ma​​in.cpp:

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QObject>

class MyClass : public QObject

    Q_OBJECT

public slots:
    void cppSlot(const QString &msg) 
        qDebug() << "Called the C++ slot with message:" << msg;
    
;


int main(int argc, char *argv[]) 
    qDebug() << "Hello World - main!";

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    MyClass myClass;
    QObject *win = engine.rootObjects()[0];
    QObject *item = win->findChild<QObject*>("myButton");

    QObject::connect(item, SIGNAL(qmlSignal(QString)),
                     &myClass, SLOT(cppSlot(QString)));

    return app.exec();

程序可以编译运行。当我运行程序时,我可以在控制台上看到这个:

QML debugging is enabled. Only use this in a safe environment.
Hello World - main!
QObject::connect: No such slot MyClass::cppSlot(QString) in ../pokus/main.cpp:30
QObject::connect:  (sender name:   'myButton')

这意味着程序正在运行但无法将 cppSlot 连接到我的按钮生成的信号上。我遇到的问题是我遵循 QML 手册,并且博客处理最复杂的问题,即我花了一天时间谷歌搜索没有任何结果..

【问题讨论】:

【参考方案1】:

您的代码无法编译:

debug/main.o: In function `MyClass::MyClass()':
/home/micurtis/dev/test/guitest/main.cpp:6: undefined reference to `vtable for MyClass'

如果我#include "main.moc" 并删除对Logic.js 的引用,当我点击“Analyzuj”时它对我有用:

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


#include "main.moc"

输出:

Starting /home/micurtis/dev/test/guitest/guitest...
QML debugging is enabled. Only use this in a safe environment.
Hello World - main!
Called the C++ slot with message: "Hello from QML"
/home/micurtis/dev/test/guitest/guitest exited with code 0

【讨论】:

以上是关于QtQuick 应用程序和 C++ 插槽绑定错误的主要内容,如果未能解决你的问题,请参考以下文章

QtQuick 动画冻结在列表和打开的串口上

QML 绑定整数属性 - c++ 中的更改未发送到 QML

在 C++ 中被动使用 QtQuick / QML

将 QStandardItemModel 从 C++ 传递到 QtQuick / QML TableView 并显示它

QML 和 C++ 属性 - ReferenceError:找不到变量

语法糖&具名插槽&作用域插槽&混入