ソースを参照

添加15章内容

cwc1987 10 年 前
コミット
25135048f6
4 ファイル変更191 行追加0 行削除
  1. 3 0
      SUMMARY.md
  2. 21 0
      qt_and_c++/README.md
  3. 166 0
      qt_and_c++/a_boilerplate_application.md
  4. 1 0
      qt_and_c++/the_qobject.md

+ 3 - 0
SUMMARY.md

@@ -102,6 +102,9 @@
    * [JavaScript语法(The Language)](javascript/the_language.md)
    * [JavaScript语法(The Language)](javascript/the_language.md)
    * [JS对象(JS Objects)](javascript/js_objects.md)
    * [JS对象(JS Objects)](javascript/js_objects.md)
    * [创建JS控制台(Creating a JS Console)](javascript/creating_a_js_console.md)
    * [创建JS控制台(Creating a JS Console)](javascript/creating_a_js_console.md)
+* [Qt and C++](qt_and_c++/README.md)
+   * [演示程序(A Boilerplate Application)](qt_and_c++/a_boilerplate_application.md)
+   * [Qt对象(The QObject)](qt_and_c++/the_qobject.md)
 * [其它(Other)](other/README.md)
 * [其它(Other)](other/README.md)
    * [协作校正](other/collaboration_correction.md)
    * [协作校正](other/collaboration_correction.md)
 
 

+ 21 - 0
qt_and_c++/README.md

@@ -0,0 +1,21 @@
+# Qt and C++
+
+Qt是QML与JavaScript的C++扩展工具包。有许多语言与Qt绑定,但是由于Qt是由C++开发的,C++的精神贯穿了整个Qt。在这一节中,我们着重从C++的角度介绍Qt,使用C++开发的本地插件来了解如何更好的扩展QML。通过C++,可以扩展和控制提供给QML的执行环境。
+
+这章将讲解Qt,正如Qt所要求的一样,需要读者有一定的C++基础知识。Qt不依赖于先进的C++特性,我认为Qt风格的C++代码可读性非常高,所以不要担心你的C++方面比较差。
+
+从C++的角度分析Qt,你会发现Qt通过内省数据的机制实现了许多现代语言的特性。这是通过使用基础类QObject实现的。内省数据,源数据,类运行时的数据维护。原生的C++是不会完成这些事情的。这使得动态查询对象信息,例如它们的属性成为可能。
+
+Qt使用源对象信息实现了信号与槽的回调绑定。每个信号能够连接任意数量的槽函数或者其它的信号。当一个信号从一个对象实例从发送后,会调用连接信号的槽函数。发送信号的对象不需要知道接收槽对象的任何信息,反之亦然。这一机制可以创建复用性非常高的组件,并减少组件之间的依赖。
+
+内省特性也用于创建动态语言的绑定,使得QML可以调用暴露的C++对象实例,并且可以从JavaScript中调用C++函数。除了绑定Qt C++, 绑定标准的JavaScript也是一种非常流行的方式,还有Python的绑定,叫做PyQt。
+
+除了这些核心概念,Qt可以使用C++开发跨平台应用程序。Qt C++在不同的操作系统上提供了一套平台抽象,允许开发者专注于手上的任务,不需要你去了解如何在不同的操作系统上打开一个文件。这意味着你可以在Windows,OS X和Linux重复编译相同的代码,由Qt去解决在不同平台上的适配问题。最终保持本地构建的应用程序与目标平台的窗口风格上看起来一致。随着移动平台的桌面更新,Qt也提供相同的代码在不同的移动平台上编译,例如IOS,Android,Jolla,BlackBerry,Ubuntu Phone,Tizen。
+
+这样不仅仅是代码可以重用,开发者的技能也可以重用。了解Qt的团队比只专注于单平台特定技能的团队可以接触更多的平台,由于Qt的灵活性,团队可以使用相同的技术创建不同平台的组件。
+
+![](http://qmlbook.github.io/_images/yourapplication.png)
+
+对于所有平台,Qt提供了一套基本类,例如支持完整unicode编码的字符串,链表容器,向量容器,缓冲容器。它也提供了目标平台的通用主循环抽象和跨平台的线程支持,网络支持。Qt的主旨是为Qt的开发者提供所有必须的功能。对于特定领域的任务,例如本地库接口,Qt也提供了一些帮助类来使得这些操作更加简单。
+
+

+ 166 - 0
qt_and_c++/a_boilerplate_application.md

@@ -0,0 +1,166 @@
+# 演示程序(A Boilerplate Application)
+
+理解Qt最好的方法是从一个小的应用程序开始。这个简单的例子叫做“Hello World!”,使用unicode编码将字符串写入到一个文件中。
+
+```
+#include <QCoreApplication>
+#include <QString>
+#include <QFile>
+#include <QDir>
+#include <QTextStream>
+#include <QDebug>
+
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication app(argc, argv);
+
+    // prepare the message
+    QString message("Hello World!");
+
+    // prepare a file in the users home directory named out.txt
+    QFile file(QDir::home().absoluteFilePath("out.txt"));
+    // try to open the file in write mode
+    if(!file.open(QIODevice::WriteOnly)) {
+        qWarning() << "Can not open file with write access";
+        return -1;
+    }
+    // as we handle text we need to use proper text codecs
+    QTextStream stream(&file);
+    // write message to file via the text stream
+    stream << message;
+
+    // do not start the eventloop as this would wait for external IO
+    // app.exec();
+
+    // no need to close file, closes automatically when scope ends
+    return 0;
+}
+```
+
+这个简单的例子演示了文件访问的使用和通过文本流使用文本编码将文本正确的写入到文件中。二进制数据的操作有一个跨平台的二进制流类叫做QDataStream。我们使用的不同类需要使用它们的类名包含。另一种是使用模块名和类名
+例如```#include <QtCore/QFile>```。对于比较懒的人,有一个更加简单的方法是包含整个模块,使用```#include <QtCore>```。例如在QtCore中你可以在应用程序中使用很多通用的类,这没有UI依赖。查看[QtCore class list](http://doc.qt.io/qt-5/qtcore-module.html)或者[QtCore overview](http://doc.qt.io/qt-5/qtcore-index.html)获取更多的信息。
+
+使用qmake和make来构建程序。QMake读取项目文件(project file)并生成一个Makefile供make使用。项目文件(project file)独立于平台,qmake会根据特定平台的设置应用一些规则来生成Makefile。在有特殊需求的项目中,项目文件也可以包含特定平台规则的平台作用域。下面是一个简单的项目文件(project file)例子。
+
+```
+# build an application
+TEMPLATE = app
+
+# use the core module and do not use the gui module
+QT       += core
+QT       -= gui
+
+# name of the executable
+TARGET = CoreApp
+
+# allow console output
+CONFIG   += console
+
+# for mac remove the application bundling
+macx {
+    CONFIG   -= app_bundle
+}
+
+# sources to be build
+SOURCES += main.cpp
+```
+
+我们不会再继续深入这个话题,只需要记住Qt项目会使用特定的项目文件(project file),qmake会根据这些项目文件和指定平台生成Makefile。
+
+上面简单的例子只是在应用程序中写入文本。一个命令行工具这是不够的。对于一个用户界面我们需要一个事件循环来等待用户的输入并安排刷新绘制操作。下面这个相同的例子使用一个桌面按钮来触发写入。
+
+令人惊奇的是我们的main.cpp依然很小。我们将代码移入到我们的类中,并使用信号槽(signal/slots)来连接用用户的输入,例如按钮点击。信号槽(signal/slot)机制通常需要一个对象,你很快就会看到。
+
+```
+#include <QtCore>
+#include <QtGui>
+#include <QtWidgets>
+#include "mainwindow.h"
+
+
+int main(int argc, char** argv)
+{
+    QApplication app(argc, argv);
+
+    MainWindow win;
+    win.resize(320, 240);
+    win.setVisible(true);
+
+    return app.exec();
+}
+```
+
+在main函数中我们简单的创建了一个应用程序对象,并使用exec()开始事件循环。现在应用程序放在了事件循环中,并等待用户输入。
+
+```
+int main(int argc, char** argv)
+{
+    QApplication app(argc, argv); // init application
+
+    // create the ui
+
+    return app.exec(); // execute event loop
+}
+```
+
+Qt提供了几种UI技术。这个例子中我们使用纯Qt C++的桌面窗口用户界面库。我们需要创建一个主窗口来放置一个触发功能的按钮,同事由主窗口来实现我们的核心功能,正如我们在上面例子上看到的。
+
+![](http://qmlbook.github.io/_images/storecontent.png)
+
+主窗口本身也是一个窗口,它是一个没有父对象的窗口。这与Qt如何定义用户界面为一个界面元素树类似。在这个例子中,主窗口是我们的根元素,按钮是主窗口上的一个子元素。
+
+```
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtWidgets>
+
+class MainWindow : public QMainWindow
+{
+public:
+    MainWindow(QWidget* parent=0);
+    ~MainWindow();
+public slots:
+    void storeContent();
+private:
+    QPushButton *m_button;
+};
+
+#endif // MAINWINDOW_H
+```
+
+此外我们定义了一个公有槽函数```storeContent()```,当点击按钮时会调用这个函数。槽函数是一个C++方法,这个方法被注册到Qt的源对象系统中,可以被动态调用。
+
+```
+#include "mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+{
+    m_button = new QPushButton("Store Content", this);
+
+    setCentralWidget(m_button);
+    connect(m_button, &QPushButton::clicked, this, &MainWindow::storeContent);
+}
+
+MainWindow::~MainWindow()
+{
+
+}
+
+void MainWindow::storeContent()
+{
+    qDebug() << "... store content";
+    QString message("Hello World!");
+    QFile file(QDir::home().absoluteFilePath("out.txt"));
+    if(!file.open(QIODevice::WriteOnly)) {
+        qWarning() << "Can not open file with write access";
+        return;
+    }
+    QTextStream stream(&file);
+    stream << message;
+}
+```
+
+在主窗口中我们首先创建了一个按钮,并将```clicked()```信号与```storeContent()```槽连接起来。每点击信号发送时都会触发调用槽函数```storeContent()```。就是这么简单,通过信号与槽的机制实现了松耦合的对象通信。

+ 1 - 0
qt_and_c++/the_qobject.md

@@ -0,0 +1 @@
+# Qt对象(The QObject)