Prechádzať zdrojové kódy

添加创建插件,fileio使用章节

cwc1987 9 rokov pred
rodič
commit
e982e54302

+ 4 - 0
SUMMARY.md

@@ -122,6 +122,10 @@
    * [理解QML运行环境(Understanding the QML Run-time)](extending_qml_with_c++/understanding_the_qml_run-time.md)
    * [插件内容(Plugin Content)](extending_qml_with_c++/plugin_content.md)
    * [创建插件(Creating the plugin)](extending_qml_with_c++/creating_the_plugin.md)
+   * [FileIO实现(FileIO Implementation)](extending_qml_with_c++/fileio_implementation.md)
+   * [使用FileIO(Using FileIO)](extending_qml_with_c++/using_fileio.md)
+       * [应用程序窗口(The Application Window)](extending_qml_with_c++/the_application_window.md)
+       * [使用动作(Using Actions)](extending_qml_with_c++/using_actions.md)
 * [其它(Other)](other/README.md)
    * [协作校正](other/collaboration_correction.md)
 

+ 15 - 7
extending_qml_with_c++/creating_the_plugin.md

@@ -1,8 +1,11 @@
 # 创建插件(Creating the plugin)
 
-Qt Creator包含了一个创建QtQuick 2 QML Extension Plugin向导,我们使用它来创建一个叫做fileio的插件,这个插件包含了一个从org.example.io中启动的FileIO对象。
+Qt Creator包含了一个创建```QtQuick 2 QML Extension
+ Plugin```向导,我们使用它来创建一个叫做```fileio```
+的插件,这个插件包含了一个从```org.example.io```中启动的```FileIO```对象。
 
-插件类源于QQmlExtensionPlugin,并且实现了registerTypes()函数。Q_PLUGIN_METADATA是强制标识这个插件作为一个qml扩展插件。除此之外没有其它特殊的地方了。
+插件类源于```QQmlExtensionPlugin```,并且实现了```registerTypes()```
+函数。```Q_PLUGIN_METADATA```是强制标识这个插件作为一个qml扩展插件。除此之外没有其它特殊的地方了。
 
 ```
 #ifndef FILEIO_PLUGIN_H
@@ -22,7 +25,7 @@ public:
 #endif // FILEIO_PLUGIN_H
 ```
 
-在实现registerTypes中我们使用qmlRegisterType函数注册了我们的FileIO类。
+在实现```registerTypes```中我们使用```qmlRegisterType```函数注册了我们的FileIO类。
 
 ```
 #include "fileio_plugin.h"
@@ -37,7 +40,7 @@ void FileioPlugin::registerTypes(const char *uri)
 }
 ```
 
-有趣的是我们不能再这里看到模块标识符(例如org.example.io)。这似乎是从外面设置的。
+有趣的是我们不能在这里看到模块统一资源标识符(例如```org.example.io```)。这似乎是从外面设置的。
 
 看你查找你的项目文件夹是,你会发现一个qmldir文件。这个文件指定了你的qml插件内容或者最好是你插件中关于QML的部分。它看起来应该像这样。
 
@@ -46,9 +49,14 @@ module org.example.io
 plugin fileio
 ```
 
+模块是统一资源标识符,在统一标识符下插件能够被其它插件获取,并且插件行必须与插件文件名完全相同(在mac下,它将是```libfileio_debug.dylib```存在于文件系统上,```fileio```在```qmldir```中)。这些文件由Qt Creator基于给定的信息创建。模块的标识符在```.pro```文件中同样可用。用来构建安装文件夹。
 
-The module is the URI under which your plugin is reachable by others and the plugin line must be identical with your plugin file name (under mac this would be libfileio_debug.dylib on the file system and fileio in the qmldir). These files where created by Qt Creator based on the given information. The module uri is also available in the .pro file. There is is used to build up the install directory.
-
-When you call make install in your build folder the library will be copied into the Qt qml folder (for Qt 5.4 on mac this would be “~/Qt/5.4/clang_64/qml”. The exact path depends on you Qt installation location and the used compiler on your system). There you will find a the library inside the “org/example/io” folder. The content are these two files currently
+当你在构建文件夹中调用```make install```时,将会拷贝库文件到Qt```qml```
+文件夹中(在Qt5.4之后mac上这将在```~/Qt/5.4/clang_64/qml```文件夹中。这个路径依赖Qt按住那个位置,并且使用系统上的编译器)。你将会在```org/example/io```文件夹中发现库文件。目前包含两个文件。
 
+```
+libfileio_debug.dylib
+qmldir
+```
 
+当导入一个叫做```org.example.io```的模块时,qml引擎将会在导入路径下查找一个可用模块并且尝试使用qmldir文件定位```org/example/io```路径。qmldir会告诉引擎使用哪个模块标识符加在哪个库作为qml扩展插件。两个模块使用相同的统一标识符将会相互覆盖。

+ 61 - 0
extending_qml_with_c++/fileio_implementation.md

@@ -0,0 +1,61 @@
+# FileIO实现(FileIO Implementation)
+
+类```FileIO```实现很简单。记住编程接口我们想要创建的像这样。
+
+```
+class FileIO : public QObject {
+    ...
+    Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+    ...
+public:
+    Q_INVOKABLE void read();
+    Q_INVOKABLE void write();
+    ...
+}
+```
+
+我们将保留属性,因为它们是简单的设置者和获取者。
+
+读取方法在读取模式下打开一个文件并且使用一个文本流读取数据。
+
+```
+void FileIO::read()
+{
+    if(m_source.isEmpty()) {
+        return;
+    }
+    QFile file(m_source.toLocalFile());
+    if(!file.exists()) {
+        qWarning() << "Does not exits: " << m_source.toLocalFile();
+        return;
+    }
+    if(file.open(QIODevice::ReadOnly)) {
+        QTextStream stream(&file);
+        m_text = stream.readAll();
+        emit textChanged(m_text);
+    }
+}
+```
+
+当文本变化时,使用```emit textChanged(m_text)```需要通知其它对象这个变化。否则属性绑定无法工作。
+
+写入方法相同,但是在写入模式下打开文件,使用文本流写入内容。
+
+```
+void FileIO::write()
+{
+    if(m_source.isEmpty()) {
+        return;
+    }
+    QFile file(m_source.toLocalFile());
+    if(file.open(QIODevice::WriteOnly)) {
+        QTextStream stream(&file);
+        stream << m_text;
+    }
+}
+```
+
+最后不要忘记调用make install。否则你的插件文件不会拷贝到qml文件夹,qml引擎无法定位模块。
+
+由于读取和写入会阻塞程序运行,你只能使用FileIO处理小型文本,否则会阻塞Qt的UI线程运行。这里一定要注意!

+ 21 - 0
extending_qml_with_c++/the_application_window.md

@@ -0,0 +1,21 @@
+# 应用程序窗口(The Application Window)
+
+使用Qt Creator的QtQuick Application向导创建一个基于QtQuick controls的应用程序。我们将不再使用新的QML格式,这在一本书里面将很难解释,即使新格式使用ui.qml文件将比之前更加容易达到目的。所以你可以移除/删除格式文件。
+
+一个应用程序窗口基础配置包含了一个工具栏,菜单栏和状态栏。我们只使用菜单栏创建一些典型的菜单条目来打开和保存文档。基础配置的窗口只会显示一个空的窗口。
+
+```
+import QtQuick 2.4
+import QtQuick.Controls 1.3
+import QtQuick.Window 2.2
+import QtQuick.Dialogs 1.2
+
+ApplicationWindow {
+    id: root
+    title: qsTr("City UI")
+    width: 640
+    height: 480
+    visible: true
+}
+```
+

+ 1 - 0
extending_qml_with_c++/using_actions.md

@@ -0,0 +1 @@
+# 使用动作(Using Actions)

+ 22 - 0
extending_qml_with_c++/using_fileio.md

@@ -0,0 +1,22 @@
+# 使用FileIO(Using FileIO)
+
+现在我们可以使用新创建的文件访问一些简单的数据。这个例子中我们想要读取一个JSON格式下的城市数据并且在表格中显示。我们将使用两个项目,一个是扩展插件项目(叫做```fileio```),提供读取和写入文件的方法。另外一个项目通过fileio读取/写入文件将数据显示在表格中(```CityUI```)。这个例子中使用的数据在```cities.json```文件中。
+
+![](http://qmlbook.github.io/_images/cityui_mock.png)
+
+JSON只是文本,它被格式化为可以转换为一个有效的JS对象/数组并返回一个文本。我们使用```FileIO```读取格式化的JSON数据并使用```JSON.parse()```将它转换为一个JS对象。数据在后面被用作一个表格视图的数据模型。我们粗略的阅读函数文档就可以获取这些内容。为了保存数据我们将转换回文本格式并使用写入函数保存。
+
+城市的JSON数据是一个格式化文本文件,包含了一组城市数据条目,每个条目包含了关于城市数据。
+
+```
+[
+    {
+        "area": "1928",
+        "city": "Shanghai",
+        "country": "China",
+        "flag": "22px-Flag_of_the_People's_Republic_of_China.svg.png",
+        "population": "13831900"
+    },
+    ...
+]
+```