QML Book 第二章 概覽

2.概覽

本章將介紹如果開始使用 Qt 5 進(jìn)行開發(fā)坑夯。將展示如何安裝 Qt SDK蔫磨,以及如何使用 Qt Creator IDE 創(chuàng)建以及運(yùn)行一個簡單的 hello world 應(yīng)用程序移袍。

提示
本章的源代碼可以在這里下載琢融。

2.1.安裝 Qt 5 SDK

Qt軟件工具包包含了編譯桌面或者嵌入式應(yīng)用程序的工具挑势。最新的版本可以從Qt-Project 主頁下載墅拭。我們將使用這種方法開始淤齐。軟件工具包自身包含了一個維護(hù)工具允許你更新到最新版本的軟件工具包股囊。

Qt 軟件工具包非常容易安裝,并且附帶了一個它自身的快速集成開發(fā)環(huán)境叫做 Qt Creator更啄。這個集成開發(fā)環(huán)境可以讓你高效的使用 Qt 進(jìn)行開發(fā)稚疹,我們推薦給所有的讀者使用。在任何況下 Qt 都可以通過命令的方式來編譯祭务,你可以自由的選擇你的代碼編輯器内狗。

當(dāng)我們開始安裝 SDK 時,最好選擇默認(rèn)的選項確保 Qt 5.x 可以使用待牵。然后一切準(zhǔn)備就緒其屏。

2.2.編寫示例程序

為了測試我們的安裝是否成功,我們可以創(chuàng)建一個簡單的應(yīng)用程序 hello world缨该。打開 Qt Creator 并且創(chuàng)建一個 Qt Quick UI Project(File -> New File 或者 Project -> Qt Quick Project -> Qt Quick UI)并且給項目取名 HelloWorld偎行。

提示:
Qt Creator 集成開發(fā)環(huán)境允許我們創(chuàng)建不同類型的應(yīng)用程序。如果沒有特別說明贰拿,我們都將默認(rèn)創(chuàng)建 Qt Quick UI Project 項目蛤袒。

提示:
典型的 Qt Quick 應(yīng)用程序是由稱為 QmlEngine 的運(yùn)行時進(jìn)行加載的,它加載初始的 QML 代碼膨更。 開發(fā)人員可以使用運(yùn)行時注冊的 C++ 類型以與本地代碼進(jìn)行接口交互妙真。這些 C++ 類型也可以綁定到一個插件中,然后使用 import 語句來動態(tài)加載荚守。qmlscene 和 qml 工具是預(yù)制的運(yùn)行時庫珍德,可以在 QML 中直接使用。一開始我們不會介紹本地化的代碼開發(fā)知識矗漾,我們將只關(guān)注 Qt 5 的 QML 方面的知識锈候。

Qt Creator 將會為我們自動地創(chuàng)建幾個文件。HellWorld.qmlproject 文件是項目文件敞贡,保存了項目的配置信息泵琳。這個文件由 Qt Creator 管理,我們不需要編輯它。

另一個文件 HelloWorld.qml 是我們的應(yīng)用程序代碼获列。打開它并嘗試看看應(yīng)用我們這個程序的作用谷市,然后繼續(xù)閱讀。

// HelloWorld.qml

import QtQuick 2.0

Rectangle {
    width: 360
    height: 360
    Text {
        anchors.centerIn: parent
        text: "Hello World"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}

這個 HelloWord.qml 是用 QML 語言編寫的击孩。我們將在下一章中更深入地討論 QML 語言迫悠。上面的代碼的意思是在一系列分層元素中描述了用戶界面:該代碼顯示了一個 360 x 360 像素的矩形,居中顯示了內(nèi)容為 “Hello World” 的文本元素溯壶,鼠標(biāo)監(jiān)聽區(qū)域覆蓋整個矩形區(qū)域及皂,當(dāng)用戶點(diǎn)擊它時,應(yīng)用程序退出且改。

接下來验烧,我們可以點(diǎn)擊
運(yùn)行

按鈕或者從菜單選擇 Bulid->Run 運(yùn)行上面的代碼。

Qt Creator 將啟動 qmlscene又跛,并將 QML 文檔作為第一個參數(shù)傳遞碍拆。 qmlscene 將解析文檔并啟動用戶界面。現(xiàn)在我們應(yīng)該可以看到下面這樣的應(yīng)用界面:

應(yīng)用界面

Qt 5 似乎在正常地工作慨蓝,我們繼續(xù)下面的內(nèi)容吧感混。

建議
如果您是系統(tǒng)集成商,您將需要安裝 Qt SDK 以獲取最新的穩(wěn)定的 Qt 版本以及根據(jù)特定設(shè)備目標(biāo)的源代碼編譯的 Qt 版本礼烈。

從頭開始構(gòu)建
如果要從命令行構(gòu)建 Qt 5弧满,首先需要獲取代碼存儲庫的副本并構(gòu)建它。

git clone git://gitorious.org/qt/qt5.git
cd qt5
./init-repository
./configure -prefix $PWD/qtbase -opensource
make -j4

在成功匯編和喝完2杯咖啡之后此熬,Qt 5 將在 qtbase 文件夾中編譯完成庭呜。其實喝任何飲料都行的,但是犀忱,我們建議喝咖啡以獲得最佳效果募谎。

如果要測試您的編譯是否成功,只需啟動 qtbase/bin/qmlscene 并選擇一個 Qt Quick 示例來運(yùn)行它......或隨我們進(jìn)入下一章阴汇。

為了測試我們的安裝数冬,我們可以創(chuàng)建一個小的 hello world 應(yīng)用程序〔笫可以使用我們喜歡的文本編輯器創(chuàng)建一個簡單的 example.qml 文件拐纱,然后粘貼以下內(nèi)容:

// HelloWorld.qml

import QtQuick 2.5

Rectangle {
    width: 360
    height: 360
    Text {
        anchors.centerIn: parent
        text: "Greetings from Qt 5"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}

我們使用如下命令并通過 Qt 5 附帶的默認(rèn)運(yùn)行環(huán)境運(yùn)行示例:

qtbase/bin/qmlscene

2.3.應(yīng)用程序類型

本節(jié)將介紹一些可能使用 Qt 5 編寫的不同應(yīng)用程序類型。它不僅限于所提供的這些內(nèi)容哥倔,但這些應(yīng)該可以讓讀者更好地了解 Qt 5 的一般功能戳玫。

2.3.1.控制臺應(yīng)用程序

控制臺應(yīng)用程序不提供任何圖形用戶界面,通常將其作為系統(tǒng)服務(wù)或通過命令行進(jìn)行調(diào)用未斑。Qt 5 附帶了一系列現(xiàn)成的組件,可幫助我們非常有效地創(chuàng)建控制臺跨平臺應(yīng)用程序。例如網(wǎng)絡(luò)文件API蜡秽、字符串處理府阀、以及自 Qt 5.1 起提供的高效命令行解析器。由于 Qt 是基于 C++ 的高級應(yīng)用程序接口芽突,我們能夠快速的編程并且程序擁有快速的執(zhí)行速度试浙。不要把 Qt 僅僅當(dāng)作是一個 UI 工具包——它其實能幫助我們做更多的事。

字符串處理

在第一個例子中我們展示了怎樣簡單的增加兩個字符串常量寞蚌。這不是一個有用的應(yīng)用程序田巴,但能讓我們了解沒有事件循環(huán)的本地端 C++ 應(yīng)用程序的大概模樣。

// module or class includes
#include <QtCore>

// text stream is text-codec aware
QTextStream cout(stdout, QIODevice::WriteOnly);

int main(int argc, char** argv)
{
    // avoid compiler warnings
    Q_UNUSED(argc)
    Q_UNUSED(argv)
    QString s1("Paris");
    QString s2("London");
    // string concatenation
    QString s = s1 + " " + s2 + "!";
    cout << s << endl;
}
容器類

這個例子在應(yīng)用程序中增加了一個鏈表和一個鏈表迭代器挟秤。Qt 自帶大量方便使用的容器類壹哺,并且其中的元素使用相同的應(yīng)用程序接口模式。

QString s1("Hello");
QString s2("Qt");
QList<QString> list;
// stream into containers
list <<  s1 << s2;
// Java and STL like iterators
QListIterator<QString> iter(list);
while(iter.hasNext()) {
    cout << iter.next();
    if(iter.hasNext()) {
        cout << " ";
    }
}
cout << "!" << endl;

下面我們顯示一些高級列表功能艘刚,它允許我們將字符串列表加入到一個字符串中管宵。 當(dāng)您需要繼續(xù)進(jìn)行基于行的文本輸入時,這非常方便攀甚。使用 QString::split() 函數(shù)可以將這個操作進(jìn)行逆向處理(將字符串轉(zhuǎn)換為字符串鏈表)箩朴。

QString s1("Hello");
QString s2("Qt");
// convenient container classes
QStringList list;
list <<  s1 << s2;
// join strings
QString s = list.join(" ") + "!";
cout << s << endl;
文件 IO

在下一個片段中,我們從本地目錄中讀取一個CSV文件秋度,并循環(huán)遍歷行炸庞,以從每行中提取內(nèi)容。為了做到這一點(diǎn)荚斯,我們需要從CSV文件中獲取大約20行的編碼埠居。文件讀取只給我們一個字節(jié)流,能夠?qū)⑵滢D(zhuǎn)換成一個有效的 Unicode 文本鲸拥,我們需要使用文本流拐格,并將文件作為較低級別的流傳遞。對于編寫CSV文件刑赶,我們只需要在寫入模式下打開文件捏浊,并將文本一行一行地輸入到文本流中。

QList<QStringList> data;
// file operations
QFile file("sample.csv");
if(file.open(QIODevice::ReadOnly)) {
    QTextStream stream(&file);
    // loop forever macro
    forever {
        QString line = stream.readLine();
        // test for null string 'String()'
        if(line.isNull()) {
            break;
        }
        // test for empty string 'QString("")'
        if(line.isEmpty()) {
            continue;
        }
        QStringList row;
        // for each loop to iterate over containers
        foreach(const QString& cell, line.split(",")) {
            row.append(cell.trimmed());
        }
        data.append(row);
    }
}
// No cleanup necessary.

至此撞叨,關(guān)于使用 Qt 進(jìn)行控制臺應(yīng)用程序的編寫介紹就告一段落金踪。

2.3.2.窗口應(yīng)用程序

基于控制臺的應(yīng)用程序非常方便,但有時您需要有一個 UI 來顯示牵敷。 此外胡岔,基于 UI 的應(yīng)用程序可能需要后端來讀/寫文件,通過網(wǎng)絡(luò)進(jìn)行通信枷餐,或?qū)?shù)據(jù)保存在容器中靶瘸。

在第一個窗口應(yīng)用程序片段中,我們根據(jù)需要盡可能少地創(chuàng)建一個窗口并顯示它。沒有父對象的窗口部件是 Qt 世界中的一個窗口怨咪。我們使用智能指針來確保當(dāng)智能指針指向范圍外時窗口會被刪除掉屋剑。應(yīng)用程序?qū)ο蠓庋b了 Qt 運(yùn)行時庫,并且通過調(diào)用 exec() 啟動事件循環(huán)诗眨。應(yīng)用程序只能對鼠標(biāo)唉匾、鍵盤或者其他事件提供程序(如網(wǎng)絡(luò)或文件 IO)觸發(fā)的事件發(fā)生響應(yīng)。當(dāng)退出事件循環(huán)時匠楚,應(yīng)用程序才會退出巍膘。這可以通過在應(yīng)用程序上調(diào)用 quit() 或關(guān)閉窗口來完成。

當(dāng)我們運(yùn)行代碼時芋簿,我們將看到一個大小為 240 x 120 像素的空白窗口峡懈。

#include <QtGui>

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QScopedPointer<QWidget> widget(new CustomWidget());
    widget->resize(240, 120);
    widget->show();
    return app.exec();
}
自定義窗口部件

當(dāng)使用用戶界面時,我們可能需要創(chuàng)建自定義的窗口部件益咬。 通常逮诲,窗口部件是一個填充繪制的窗口區(qū)域。另外幽告,窗口部件具有如何處理鍵盤或鼠標(biāo)輸入以及如何對外部觸發(fā)器做出反應(yīng)的內(nèi)部知識梅鹦。為了在 Qt 中做這些,我們需要從 QWidget 派生并覆蓋繪畫和事件處理的幾個函數(shù)冗锁。

#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H

#include <QtWidgets>

class CustomWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CustomWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
private:
    QPoint m_lastPos;
};

#endif // CUSTOMWIDGET_H

在實現(xiàn)中齐唆,我們在窗口部件上繪制一個小邊框,并在最后一個鼠標(biāo)位置上繪制一個小矩形冻河。這對于低級別的自定義窗口部件是非常典型的箍邮。鼠標(biāo)或鍵盤事件會更改窗口部件的內(nèi)部狀態(tài)并觸發(fā)繪畫更新。我們不會在這段代碼中詳細(xì)介紹叨叙,但是希望你知道我們有這個能力锭弊。Qt 帶有一大批現(xiàn)成的桌面小部件,因此我們不必自定義窗口部件的概率很高擂错。

#include "customwidget.h"

CustomWidget::CustomWidget(QWidget *parent) :
    QWidget(parent)
{
}

void CustomWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QRect r1 = rect().adjusted(10,10,-10,-10);
    painter.setPen(QColor("#33B5E5"));
    painter.drawRect(r1);

    QRect r2(QPoint(0,0),QSize(40,40));
    if(m_lastPos.isNull()) {
        r2.moveCenter(r1.center());
    } else {
        r2.moveCenter(m_lastPos);
    }
    painter.fillRect(r2, QColor("#FFBB33"));
}

void CustomWidget::mousePressEvent(QMouseEvent *event)
{
    m_lastPos = event->pos();
    update();
}

void CustomWidget::mouseMoveEvent(QMouseEvent *event)
{
    m_lastPos = event->pos();
    update();
}
桌面窗口部件

Qt 開發(fā)人員已經(jīng)為您完成了所有這些工作味滞,并提供了一組桌面小部件,它們將在不同的操作系統(tǒng)上看起來很像是原生的窗口部件钮呀。然后剑鞍,我們的工作就是將部件容器中的這些不同的部件排列成更大的面板。Qt中的小部件也可以是其他小部件的容器爽醋。這是通過親子關(guān)系來實現(xiàn)的蚁署。。這意味著我們需要準(zhǔn)備類似按鈕(button)蚂四,復(fù)選框(check box)光戈,單選按鈕(radio button)的窗口部件并且對它們進(jìn)行布局哪痰。完成此操作的一種方法如下所示。

這是一個所謂的 widget 容器的頭文件久妆。

class CustomWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CustomWidget(QWidget *parent = 0);
private slots:
    void itemClicked(QListWidgetItem* item);
    void updateItem();
private:
    QListWidget *m_widget;
    QLineEdit *m_edit;
    QPushButton *m_button;
};

在實現(xiàn)中妒御,我們使用布局來更好地安排我們的小部件。 當(dāng)容器小部件重新調(diào)整大小時镇饺,布局管理器會根據(jù)某些大小策略重新布置小部件。在這個例子中送讲,我們有一個列表奸笤,一個行編輯和一個垂直排列的按鈕,可以編輯城市列表哼鬓。我們使用 Qt 的信號和槽來連接發(fā)送器和接收器對象监右。

CustomWidget::CustomWidget(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout(this);
    m_widget = new QListWidget(this);
    layout->addWidget(m_widget);

    m_edit = new QLineEdit(this);
    layout->addWidget(m_edit);

    m_button = new QPushButton("Quit", this);
    layout->addWidget(m_button);
    setLayout(layout);

    QStringList cities;
    cities << "Paris" << "London" << "Munich";
    foreach(const QString& city, cities) {
        m_widget->addItem(city);
    }

    connect(m_widget, SIGNAL(itemClicked(QListWidgetItem*)), 
            this, SLOT(itemClicked(QListWidgetItem*)));
    connect(m_edit, SIGNAL(editingFinished()), this, SLOT(updateItem()));
    connect(m_button, SIGNAL(clicked()), qApp, SLOT(quit()));
}

void CustomWidget::itemClicked(QListWidgetItem *item)
{
    Q_ASSERT(item);
    m_edit->setText(item->text());
}

void CustomWidget::updateItem()
{
    QListWidgetItem* item = m_widget->currentItem();
    if(item) {
        item->setText(m_edit->text());
    }
}
繪制圖形

有一些問題最好用可視化的方式表達(dá)。如果手邊的問題看起來有點(diǎn)像幾何對象异希,qt graphics view 是一個很好的選擇健盒。一個圖形視窗(graphics view)能夠在一個場景(scene)排列簡單的幾何圖形。用戶可以與這些圖形交互称簿,它們使用一定的算法放置在場景(scene)上扣癣。填充一個圖形視圖你需要一個圖形窗口(graphics view)和一個圖形場景(graphics scene)。一個圖形場景(scene)連接在一個圖形窗口(view)上娇斑,圖形對象(graphics item)是被放在圖形場景(scene)上的萎战。這里有一個簡單的例子眼溶,首先頭文件定義了圖形窗口(view)與圖形場景(scene)。

class CustomWidgetV2 : public QWidget
{
    Q_OBJECT
public:
    explicit CustomWidgetV2(QWidget *parent = 0);
private:
    QGraphicsView *m_view;
    QGraphicsScene *m_scene;

};

在實現(xiàn)中首先將圖形場景(scene)與圖形窗口(view)連接士嚎。圖形窗口(view)是一個窗口部件,能夠被我們的窗口部件容器包含悔叽。最后我們添加一個小的矩形框在圖形場景(scene)中莱衩。然后它會被渲染到我們的圖形窗口(view)上。

#include "customwidgetv2.h"

CustomWidget::CustomWidget(QWidget *parent) :
    QWidget(parent)
{
    m_view = new QGraphicsView(this);
    m_scene = new QGraphicsScene(this);
    m_view->setScene(m_scene);

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setMargin(0);
    layout->addWidget(m_view);
    setLayout(layout);

    QGraphicsItem* rect1 = m_scene->addRect(0,0, 40, 40, Qt::NoPen, QColor("#FFBB33"));
    rect1->setFlags(QGraphicsItem::ItemIsFocusable|QGraphicsItem::ItemIsMovable);
}

2.3.3. 數(shù)據(jù)適配

到目前為止娇澎,我們主要涵蓋基本數(shù)據(jù)類型以及如何使用視圖部件和圖形視圖笨蚁。通常在我們的應(yīng)用程序中,我們將需要更大量的結(jié)構(gòu)化數(shù)據(jù)九火,也必須持續(xù)存儲赚窃。數(shù)據(jù)也需要顯示。對于這個 Qt 使用的模型岔激。一個簡單的模型是字符串列表模型勒极,它被字符串填充,然后附加到列表視圖虑鼎。

m_view = new QListView(this);
m_model = new QStringListModel(this);
view->setModel(m_model);

QList<QString> cities;
cities << "Munich" << "Paris" << "London";
model->setStringList(cities);

另一個比較普遍的用法是使用 SQL(結(jié)構(gòu)化數(shù)據(jù)查詢語言)來存儲和讀取數(shù)據(jù)辱匿。Qt 自身附帶了內(nèi)嵌版的 SQLLite 并且也支持其它的數(shù)據(jù)引擎(比如 MySQL键痛,PostgresSQL,等等)匾七。首先你需要使用一個模式來創(chuàng)建你的數(shù)據(jù)庫絮短,比如像這樣:

CREATE TABLE city (name TEXT, country TEXT);
INSERT INTO city value ("Munich", "Germany");
INSERT INTO city value ("Paris", "France");
INSERT INTO city value ("London", "United Kingdom");

為了能夠在使用 sql,我們需要在我們的項目文件(*.pro)中加入 sql 模塊昨忆。

QT += sql

然后我們可以使用 C++ 打開我們的數(shù)據(jù)庫丁频。首先,我們需要檢索指定數(shù)據(jù)庫引擎的新數(shù)據(jù)庫對象邑贴。使用此數(shù)據(jù)庫對象席里,我們打開數(shù)據(jù)庫。對于 SQLite 這樣的數(shù)據(jù)庫我們可以指定一個數(shù)據(jù)庫文件的路徑拢驾。Qt提供了一些高級的數(shù)據(jù)庫模型奖磁,其中有一種表格模型(table model)使用表格標(biāo)示符和一個選項分支語句(where clause)來選擇數(shù)據(jù)。這個模型的結(jié)果能夠與一個鏈表視圖連接繁疤,就像之前連接其它數(shù)據(jù)模型一樣咖为。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName('cities.db');
if(!db.open()) {
    qFatal("unable to open database");
}

m_model = QSqlTableModel(this);
m_model->setTable("city");
m_model->setHeaderData(0, Qt::Horizontal, "City");
m_model->setHeaderData(1, Qt::Horizontal, "Country");

view->setModel(m_model);
m_model->select();

對于更高級別的模型操作,Qt 提供了一個排序文件代理模型稠腊,允許我們使用基礎(chǔ)的分類排序和數(shù)據(jù)過濾來操作其它的模型躁染。

QSortFilterProxyModel* proxy = new QSortFilterProxyModel(this);
proxy->setSourceModel(m_model);
view->setModel(proxy);
view->setSortingEnabled(true);

過濾是基于要過濾的列和一個字符串作為過濾器參數(shù)完成的。

proxy->setFilterKeyColumn(0);
proxy->setFilterCaseSensitive(Qt::CaseInsensitive);
proxy->setFilterFixedString(QString)

過濾器代理模型實際上比這里演示得更強(qiáng)大÷檠現(xiàn)在我們記住存在這樣一個強(qiáng)大的工具就足夠了褐啡。

提示
這里是綜述了我們可以在 Qt 5 中開發(fā)的不同類型的經(jīng)典應(yīng)用程序。桌面應(yīng)用程序正在發(fā)生著改變鳖昌,不久之后移動設(shè)備將會占據(jù)我們的世界备畦。移動設(shè)備的用戶界面設(shè)計非常不同。它們相對于桌面應(yīng)用程序更加簡潔许昨,只需要專注的做一件事情懂盐。動畫效果是一個非常重要的部分,用戶界面需要生動活潑糕档。傳統(tǒng)的 Qt 技術(shù)已經(jīng)不適于這些市場了莉恼。

2.3.4. Qt Quick 應(yīng)用

在現(xiàn)代的軟件開發(fā)中有一個內(nèi)在的沖突,用戶界面的改變速度遠(yuǎn)遠(yuǎn)高于我們的后端服務(wù)速那。在傳統(tǒng)的技術(shù)中我們開發(fā)的前端需要與后端保持相同的步調(diào)俐银。當(dāng)一個項目在開發(fā)時用戶想要改變用戶界面,或者在一個項目中開發(fā)一個用戶界面的想法就會引發(fā)這個沖突端仰。敏捷的項目需要敏捷的方法捶惜。

Qt Quick 提供了一個類似 HTML 聲明語言的環(huán)境應(yīng)用程序作為你的用戶界面前端(the front-end),在你的后端使用本地的 C++ 代碼荔烧。這使我們能夠獲得兩端的最佳的開發(fā)效果吱七。

下面是一個簡單的 Qt Quick UI:

import QtQuick 2.5

Rectangle {
    width: 240; height: 1230
    Rectangle {
        width: 40; height: 40
        anchors.centerIn: parent
        color: '#FFBB33'
    }
}

這種聲明語言被稱作 QML汽久,它需要運(yùn)行時才能執(zhí)行。Qt 提供了一個典型的叫做 qmlscene 的運(yùn)行環(huán)境踊餐,但是想要寫一個自定義的運(yùn)行環(huán)境也不是很困難景醇,為此,我們需要一個 quick view 并且將 QML 文檔作為它的資源吝岭。剩下的事情就只是顯示用戶界面了三痰。

QQuickView* view = new QQuickView();
QUrl source = QUrl::fromLocalFile("main.qml");
view->setSource(source);
view.show();

回到我們早前的例子中。 在這個例子中窜管,我們使用了一個 C++ 城市模型酒觅。如果我們可以在我們聲明的 QML 代碼中使用這個模型,那就再好不過了微峰。

為了實現(xiàn)這一點(diǎn),我們首先編寫我們的前端抒钱,看看我們將如何使用城市模型蜓肆。在這種情況下,前端需要一個名為 cityModel 的對象谋币,我們可以在列表視圖中使用它仗扬。

import QtQuick 2.5

Rectangle {
    width: 240; height: 120
    ListView {
        width: 180; height: 120
        anchors.centerIn: parent
        model: cityModel
        delegate: Text { text: model.city }
    }
}

為了啟用 cityModel,我們可以復(fù)用我們以前的模型蕾额,并將context屬性添加到我們的 root context 中(root context 是主文檔中的另一個 root-element)早芭。

m_model = QSqlTableModel(this);
... // some magic code
QHash<int, QByteArray> roles;
roles[Qt::UserRole+1] = "city";
roles[Qt::UserRole+2] = "country";
m_model->setRoleNames(roles);
view->rootContext()->setContextProperty("cityModel", m_model);

注意
這不是完全正確的用法,作為包含在 SQL 表格模型列中的數(shù)據(jù)诅蝶,一個 QML 模型的任務(wù)是來表達(dá)這些數(shù)據(jù)退个。所以需要做一個在列和任務(wù)之間的映射關(guān)系。請查看 QML 和 QSqlTableModel 幫助文檔獲得更詳細(xì)的信息调炬。

2.4. 總結(jié)

我們已經(jīng)看到如何安裝 Qt SDK 以及如何創(chuàng)建我們的第一個應(yīng)用程序语盈。然后,我們介紹了不同的應(yīng)用程序類型缰泡,以概述 Qt刀荒,展示了 Qt 為應(yīng)用程序開發(fā)提供的一些功能。希望這些能使大家對 Qt 有一個初步的印象棘钞,Qt 是一個非常豐富的用戶界面工具包缠借,并提供應(yīng)用程序開發(fā)人員可以期待的一切。不過宜猜,Qt 并不會將您鎖定到特定的庫中泼返,因為您可以隨時使用其他庫或者擴(kuò)展 Qt。Qt 對于不同類型的應(yīng)用程序開發(fā)支持非常豐富:包括控制臺程序宝恶,經(jīng)典的桌面用戶界面程序和觸屏用戶界面程序符隙。

本文參考鏈接:Get Started

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趴捅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子霹疫,更是在濱河造成了極大的恐慌拱绑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丽蝎,死亡現(xiàn)場離奇詭異猎拨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)屠阻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門红省,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人国觉,你說我怎么就攤上這事吧恃。” “怎么了麻诀?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵痕寓,是天一觀的道長。 經(jīng)常有香客問我蝇闭,道長呻率,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任呻引,我火速辦了婚禮礼仗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逻悠。我一直安慰自己元践,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布童谒。 她就那樣靜靜地躺著卢厂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惠啄。 梳的紋絲不亂的頭發(fā)上慎恒,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音撵渡,去河邊找鬼融柬。 笑死,一個胖子當(dāng)著我的面吹牛趋距,可吹牛的內(nèi)容都是我干的粒氧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼节腐,長吁一口氣:“原來是場噩夢啊……” “哼外盯!你這毒婦竟也來了摘盆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤饱苟,失蹤者是張志新(化名)和其女友劉穎孩擂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箱熬,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡类垦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了城须。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚤认。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖糕伐,靈堂內(nèi)的尸體忽然破棺而出砰琢,到底是詐尸還是另有隱情,我是刑警寧澤良瞧,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布氯析,位于F島的核電站,受9級特大地震影響莺褒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雪情,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一遵岩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧巡通,春花似錦尘执、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弥锄,卻和暖如春丧靡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背籽暇。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工温治, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戒悠。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓熬荆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绸狐。 傳聞我的和親對象是個殘疾皇子卤恳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • QML 性能上的注意事項和建議 趙者也[http://www.reibang.com/u/7b2ff27d6fd...
    趙者也閱讀 16,038評論 1 11
  • 1.初識 Qt5 本書將為大家介紹使用 Qt 5.x 版本開發(fā)應(yīng)用程序的不同方面累盗。我們將專注于新的 Qt Quic...
    趙者也閱讀 2,575評論 0 8
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,162評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)突琳,斷路器若债,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 昨天終于看了那部我想看的電影,《摔跤吧本今,爸爸》拆座。這部電影評分很高而它確實值得擁有這個分?jǐn)?shù)。阿米爾汗是一個很棒的演員...
    風(fēng)鈴兒風(fēng)鈴兒閱讀 199評論 0 0