开发Qt Plugin 3

现在看一下hello.pro文件:

TEMPLATE = lib
CONFIG += plugin
QT += qml
DESTDIR = imports/demo
TARGET  = hello
SOURCES += plugin.cpp
qml.files = test.qml
qml.path += ./
pluginfiles.files += \
    imports/demo/qmldir \
    imports/demo/hello.qml \
pluginfiles.path += imports/demo
target.path += imports/demo
INSTALLS += target qml pluginfiles

这是一个qmake project file. 官方文档在这里:

http://qt-project.org/doc/qt-5/qmake-project-files.html
http://qt-project.org/doc/qt-5/qmake-language.html


qmake读取这个文件,然后产生Makefile。在运行qmake命令之前,让我们看一下如何在plugin.cpp文件中实现一个可导出的C++类。

#include <QtQml/QQmlExtensionPlugin>
#include <QtQml/qqml.h>
#include <qdebug.h>
#include <qdatetime.h>
#include <qbasictimer.h>
#include <qcoreapplication.h>
//![0]
class ClickHandler : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QString value READ value)
  //![0]
public:
  ClickHandler(QObject *parent=0) : QObject(parent)
  {
  }
  ~ClickHandler()
  {
  }
  QString value() const {
    return "hello, world";
  }
};
//![plugin]
class QExampleQmlPlugin : public QQmlExtensionPlugin
{
  Q_OBJECT
  Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
  public:
  void registerTypes(const char *uri)
  {
    qmlRegisterType<ClickHandler>(uri, 1, 0, "MyClick");
  }
};
//![plugin]
#include "plugin.moc"

要实现它,需要下面的步骤:

1. 从QQmlExtensionPlugin类继承,并使用上面的Q_宏

2. 定义一个你要导出的类,这里我有一个ClickHandler类。然后在上面的类的registerTypes方法中注册这个导出类的名字,包括版本号和short name.

3. 不要忘记plugin.moc文件需要引入。

上面的代码并不长,但是包含了很多细节。请参考官方文档获得更多信息:

http://doc-snapshot.qt-project.org/qdoc/qtqml-cppintegration-definetypes.html
http://doc-snapshot.qt-project.org/qdoc/qml-extending-tutorial-index.html
http://doc-snapshot.qt-project.org/qdoc/qtqml-cppintegration-exposecppattributes.html
http://doc-snapshot.qt-project.org/qdoc/qqmlextensionplugin.html


现在,运行命令构建项目

dean@sloop2:~/test/plugin$ qmake
dean@sloop2:~/test/plugin$ make
/home/dean/Qt5.2.0/5.2.0/gcc_64/bin/moc -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../Qt5.2.0/5.2.0/gcc_64/mkspecs/linux-g++ -I. -I../../Qt5.2.0/5.2.0/gcc_64/include -I../../Qt5.2.0/5.2.0/gcc_64/include/QtQml -I../../Qt5.2.0/5.2.0/gcc_64/include/QtNetwork -I../../Qt5.2.0/5.2.0/gcc_64/include/QtGui -I../../Qt5.2.0/5.2.0/gcc_64/include/QtCore -I. plugin.cpp -o plugin.moc
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../Qt5.2.0/5.2.0/gcc_64/mkspecs/linux-g++ -I. -I../../Qt5.2.0/5.2.0/gcc_64/include -I../../Qt5.2.0/5.2.0/gcc_64/include/QtQml -I../../Qt5.2.0/5.2.0/gcc_64/include/QtNetwork -I../../Qt5.2.0/5.2.0/gcc_64/include/QtGui -I../../Qt5.2.0/5.2.0/gcc_64/include/QtCore -I. -o plugin.o plugin.cpp
rm -f libhello.so
g++ -Wl,-O1 -Wl,-rpath,/home/dean/Qt5.2.0/5.2.0/gcc_64 -Wl,-rpath,/home/dean/Qt5.2.0/5.2.0/gcc_64/lib -shared -o libhello.so plugin.o  -L/home/dean/Qt5.2.0/5.2.0/gcc_64/lib -lQt5Qml -lQt5Network -lQt5Gui -lQt5Core -lGL -lpthread 
mv -f libhello.so imports/demo/ 

从上面的输出,你会看到qmake 使用了Qt5.2.0自带的moc 从plugin.cpp文件中生成plugin.moc. 要想了解moc,你需要学些一些关于Qt Meta-Object System的知识。

http://qt-project.org/doc/qt-5/metaobjects.html


在正式的项目中,可能有好几个类都从extensionplugin中暴露出来,并且有自己的.h和.cpp文件。

注意,必须在pro文件中将.h文件添加到HEADERS中,比如:

HEADERS += piechart.h
SOURCES += plugin.cpp piechart.cpp

否则moc命令将不会被正确调用,最终导致出现undefined symbol错误。

$ ldd -r imports/demo/libhello.so
	linux-vdso.so.1 =>  (0x00007fffea7fe000)
	libQt5Qml.so.5 => /home/dean/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Qml.so.5 (0x00007f6f971fb000)
	libQt5Core.so.5 => /home/dean/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Core.so.5 (0x00007f6f96b2e000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6f9680e000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6f965f8000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f96230000)
	libQt5Network.so.5 => /home/dean/Qt5.2.0/5.2.0/gcc_64/lib/libQt5Network.so.5 (0x00007f6f95edb000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6f95cbe000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6f959ba000)
	libicui18n.so.51 => /home/dean/Qt5.2.0/5.2.0/gcc_64/lib/libicui18n.so.51 (0x00007f6f955a0000)
	libicuuc.so.51 => /home/dean/Qt5.2.0/5.2.0/gcc_64/lib/libicuuc.so.51 (0x00007f6f9521a000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6f95016000)
	libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f6f94e13000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6f94c0b000)
	libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f6f9490a000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f6f97a10000)
	libicudata.so.51 => /home/dean/Qt5.2.0/5.2.0/gcc_64/lib/libicudata.so.51 (0x00007f6f931c0000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f6f92f81000)
undefined symbol: _ZTI12ClickHandler	(imports/demo/libhello.so)
undefined symbol: _ZNK12ClickHandler10metaObjectEv	(imports/demo/libhello.so)
undefined symbol: _ZN12ClickHandler11qt_metacastEPKc	(imports/demo/libhello.so)
undefined symbol: _ZN12ClickHandler11qt_metacallEN11QMetaObject4CallEiPPv	(imports/demo/libhello.so)
undefined symbol: _ZN12ClickHandler16staticMetaObjectE	(imports/demo/libhello.so)
undefined symbol: _ZTV12ClickHandler	(imports/demo/libhello.so)


qmake文档:

http://doc-snapshot.qt-project.org/qdoc/qmake-variable-reference.html



你可能感兴趣的:(qt,qml)