无法使 qmlRegisterType 工作 [英] Unable to make qmlRegisterType work

查看:26
本文介绍了无法使 qmlRegisterType 工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在互联网上找到了一些 qmlRegisterType 的示例,但无法使其正常工作.我新建一个 Qt Quick 2 项目并添加以下内容:

I've found some examples of qmlRegisterType on the internet but just can't make it work. I create a new Qt Quick 2 project and add the following contents:

这是我的 .pro 文件:

This is my .pro file:

#Add more folders to ship with the application, here
folder_01.source = qml/testlib
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01

#Libraries
QT += core gui widgets

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

#Header files
HEADERS += main.hpp

#The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp

#Installation path
#target.path =

#Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()

这是我的代码文件(main.cpp):

This is my code file (main.cpp):

#include <QtQml>
#include <QtWidgets/QApplication>
#include "qtquick2applicationviewer.h"

//test class
class TestClass:public QObject {
  Q_OBJECT

  public:
    TestClass(QObject* parent=0):QObject(parent){}

  public slots:
    void test() {
      qDebug("test!");
    }
};

//entry point
int main(int argc, char *argv[]) {

  //create application
  QApplication app(argc, argv);

  //register custom qml component
  qmlRegisterType<TestClass>("testlib",1,0,"TestClass");

  //create and show qml viewer
  QtQuick2ApplicationViewer viewer;
  viewer.setMainQmlFile(QStringLiteral("qml/testlib/main.qml"));
  viewer.showExpanded();

  //back to OS
  return app.exec();
}

这是我的 QML 文件 (main.qml):

This is my QML file (main.qml):

import QtQuick 2.0
import testlib 1.0

Rectangle {

  TestClass {
    id:testobj
  }

  Component.onCompleted: {
    testobj.test();
  }
}

但我面临多个链接错误:

  • 对 `vtable for TestClass' 的未定义引用
  • 对 `TestClass::staticMetaObject' 的未定义引用
  • 对 `TestClass::metaObject() const' 的未定义引用
  • 对 `TestClass::qt_metacast(char const*)' 的未定义引用
  • 对 `TestClass::qt_metacall(QMetaObject::Call, int, void**)' 的未定义引用

我正在使用随 MinGW 4.8 稳定版一起提供的 Qt 5.2.1.这些错误意味着链接器找不到包含方法实现的库文件(如上所述).发生了什么?可能无法在 Qt 5 上编译,但在 Qt 4 上可以?

I'm using Qt 5.2.1 shipped with MinGW 4.8 stable. These errors mean the linker can not find library files which contain method implementations (stated above). What happened? May be fail to compile on Qt 5 but ok on Qt 4?

推荐答案

Qt编译注意事项:

(1) Use 'QT +=' in .pro file for Qt headers & Qt libraries

(2) Use 'HEADERS +=' and 'SOURCES +=' in .pro file for 
project level headers and source codes

关于创建自定义 QML 组件(以下称为CustomCom")的注意事项:

Notes about creating a custom QML component (herefrom called 'CustomCom'):

(1) Inherit publically 'CustomCom' from QQuickItem: 

class CustomCom:public QQuickItem {}

(2) Put the Q_OBJECT macro right after first line of 
class 'CustomCom' declaration.

(3) Inherit the constructor:

public: CustomCom(QQuickItem* parent=0):QQuickItem(parent){}

(4) Put the methods to be called by JS after "public slots:"

(5) Call 'qmlRegisterType' after creation of 'QApplication' and
before creating any QML view or viewer.

(6) IMPORTANT: If you fail to compile with error 
'undefined reference to vtable...", just put the code of 'CustomCom.cpp'
nested inside the 'CustomCom.hpp' file, and put the whole code 
of the class 'CustomCom.hpp' in the main header file because of
something wrong in header referencing. 

示例头代码:

[main.hpp]
class CustomCom:public QQuickItem {
  Q_OBJECT

  public:
    CustomCom(QQuickItem* parent=0):QQuickItem(parent){}

  public slots:
    void test() {
      qDebug("Test!");
    }
};

示例源代码:

[main.cpp]
int main(int argc,char** args) {
  QApplication* app = new QApplication(argc,args);

  //call before any qml may use the custom component
  qmlRegisterType<CustomCom>("CustomLib",1,0,"CustomCom");

  //class 'QtQuick2ApplicationViewer' is generated by Qt Creator
  //when creating new Quick 2 project. The path to 'main.qml'
  //may be different
  QtQuick2ApplicationViewer* viewer = new QtQuick2ApplicationViewer();
  viewer->setMainQmlFile("qml/project/main.qml");
  viewer->showExpanded();
}

QML 示例:

[main.qml]
import QtQuick 2.0
import CustomLib 1.0

Rectangle {
  width:640; height:360;

  CustomCom {
    id:customcom;
  }

  Component.onCompleted: {
    customcom.test();
  }
}

问题的解决方案(面对'未定义的vtable引用'):

Solution to the question (facing 'Undefined reference to vtable'):

  • 结合TestClass.hpp"和'TestClass.cpp' 到 'TestClass.hpp' 文件中
  • 将'TestClass.hpp'的内容移动到'main.hpp'

问题是由使用主头文件引起的.仅在需要时添加#include(s) 可以解决问题.

The problem was caused by using master header file. Putting the #include(s) only when needed solves the problem.

这篇关于无法使 qmlRegisterType 工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆