甘薇的父亲是干什么的,想知道他最近在贴吧干了些什么

君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
QML我们如何与C++一起使用
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口Qt点滴(7)
为了在C++中使用QML,用到了QtDeclarative中有三个主要的类:QDeclarativeEngine、QDeclarativeComponent和QDeclarativeContext。很多QML元素也有对应方法获取用C++创建好的元素实例,如:Item&-&QDeclarativeItem、Scale&-&QGraphicsScale、Blur&-&QGraphicsBlurEffect。为了使用QtDeclarative,需要在工程文件中加入QT
+= declarative
二、QDeclarativeView
这是一个简单易用的显示类,继承自QGraphicsView,主要用于快速的建立应用原型
示例如下:
#include &QApplication&
#include &QtDeclarative/QDeclarativeView&
int main(int argc, char *argv[])
QApplication app(argc, argv);
QDeclarativeView canvas;
canvas.setSource(QUrl(&main.qml&));
canvas.show();
return app.exec();
三、QDeclarativeEngine
若想要在Qt/C++中访问QML,必须有一个QDeclarativeEngine实例。其提供了在C++中初始化QML控件的环境,通过它配置全局的QML设置。如果要提供不同的QML设置,需要实例化多个QDeclarativeEngine
四、QDeclarativeComponent
它对应了一个QML文档的实例,用来加载QML文件。加载的内容可以是路径,也可以是QML代码(URL可以是本地的文件或者QNetworkAccessManager支持的协议访问的网络文件)。这个类还包含了QML文件的状态信息,如:Null、Ready、Loading、Error等。
五、实例——初始化组件
// Create the engine(root context create automatically as well
QDeclarativeEngine engine;
// Create a QML component associated with the engine
// (Alternatively you could create an empty component and the set
// its contents with setData().)
QDeclarativeComponent component(&engine, QUrl(&main.qml&));
// Instantiate the component (as no context is given to create(),
// the root context is used by default
QDeclarativeItem* item = qobject_cast&QDeclarativeItem*&(component.create());
// Add item to a view, etc...
六、QDeclarativeContext
1、每个QML组件初始化都会对应一个QDeclarativeContext(engine会自动建立root context)。子context可以根据需要而创建,它与父类的集成关系是由QDeclarativeEngine管理维护的。QML组件实例的数据都应该加入到engine的root环境中,同时,QML子组件的数据也应该加入到子环境中(sub-context)
2、使用context可以把C++的数据和对象暴露给QML
示例如下:
QQmlApplicationEngine engine;
// engine.rootContext() returns a QDeclarativeContext*
engine.rootContext()-&setContextProperty(&myBackgroundColor&,
QColor(Qt::lightsteelblue));
QDeclarativeComponent component(&engine, &main.qml&);
QObject* window = component.create(); // Create using the root context
3、这种机制可以被用来为QML中的View提供C++端的Model
4、前面提到过,context是具有继承关系的,控件初始化的时候,可以使用对应的context里的数据,也可以访问到祖先context的数据。对于重复定义的数据,子context中的定义将会覆盖context中的定义
示例如下:
QDeclarativeEngine engine;
QDeclarativeContext context1(engine.rootContext());
QDeclarativeContext context2(&context1);
QDeclarativeContext context3(&context2);
context1.setContextProperty(&a&, 12);
context2.setContextProperty(&b&, 13);
context3.setContextProperty(&a&, 14);
context3.setContextProperty(&c&, 14);
// Instantiate QDeclarativeComponents using the sub-context
component1.create(&context1); // a = 12
component2.create(&context2); // a = 12, b = 13
component3.create(&context3); // a = 14, b = 13, c = 14
七、结构化数据
1、如果有很多数据需要暴露给QML,可以使用默认对象(default object)代替。所有默认对象中定义的属性都可以在QML控件中通过名字访问到。通过这种方式暴露的数据,可以在QML端被修改。同时,使用默认对象的速度比多次调用setContextProperty()快。
2、多个默认对象可以加到同一个QML组件实例中,先添加的默认对象是不会被后面添加的对象所覆盖。于此不同的是,使用setContextProperty()设置的属性,会被新的属性覆盖。
3、Model数据通常都是由C++端代码动态提供的,而不是一个静态QML的数据Model。在delegate里面通过model属性可以访问到数据模型,这是一个默认的属性。
4、可以使用的C++端的数据模型有:
& & QList&QObject*& —— model.modelData.xxx(xxx是属性)
& & QAbstractDataModel —— model.display(decoration)
& & QStringList —— model.modelData
示例如下:
// MyDataSet.h
class MyData : ... {
// The NOTIFY signal informs about changes in the property's value
Q_PROPERTY(QAbstractItemModel* myModel READ model NOTIFY modelChanged)
Q_PROPERTY(QString text READ text NOTIFY textChanged)
// SomeOtherPieceOfCode.cpp exposes the QObject using e.g. a sub-context
QDeclarativeEngine engine;
QDeclarativeContext context(engine.rootContext());
context.addContextObject(new MyDataSet(...));
QDeclarativeComponent component(&engine, &ListView {model = myModel}&);
component.create(&context);
八、QML调用C++方法
所有QObject对象的public的槽方法都可以在QML中调用,如果你不想你的方法是槽方法,可以使用Q_INVOKABLE(如:Q_INVOKABLE void myMethod();)
// In C++:
class LEDBlinker : public QObject {
public slots:
bool isRunning();
void start();
void stop();
int main(int argc, char *argv[]){
QDeclarativeContext* context = engine-&rootContext();
context-&setContextProperty(&ledBlinker&, new LEDBlinker);
// In QML:
Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
if (ledBlinker.isRunning())
ledBlinker.stop()
ledBlinker.start();
需要注意的是,我们完全可以通过声明一个“running”属性来达到同样的效果,这样的话,代码会更加优雅,省略掉了isRunning()和setRunning()两个方法
// In C++:
class LEDBlinker : public QObject {
Q_PROPERTY(bool running READ isRunning WRITE setRunning)
// In QML:
Rectangle {
MouseArea {
anchors.fill: parent
onClicked: ledBlinker.running = !ledBlinker.running
九、在C++中调用QML方法
很明显,反过来在C++中调用QML的方法也是可以的。在QML中定义的方法在C++中都是一个槽函数,同时,在QML中定义的信号可以与C++中定义的槽函数连接。
十、网络组件
前面讨论过,QML组件可以通过网络加载,这种方式可能会花费些时间,因为网络总是有一定的延时。所以,在C++中初始化网络上的QML控件的时候,需要观察控件的加载状态,只有当状态为Ready后,才能调用created()创建控件。
示例如下:
MyObject::MyObject() {
component = new QDeclarativeComponent(engine,
QUrl(&/mail.qml&));
// Check for status before creating the object - notice that this kind of
// code could (should?) be used regardless of where the component is located!
if(component-&isLoading())
connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status),
this, SLOT(continueLoading())));
continueLoading(); // Not a network-based resource, load straight away
// A slot that emits the States parameter of the signal and uses the isXxxx()
// functions instead to check the status - both approaches work the same way
void MyObject::continueLoading() {
if(component-&isError()){
qWarning() && component-&errors();
} else if(component-&isReady()) {
QObject* myObject = component-&create();
} // The other status checks here ...
十一、QML Components in Resource File
在Qt工程中最方便的方法还是把QML组件添加到资源文件中,所有的JavaScript文件也可以被放在资源文件中。这样更加容易访问文件,放入资源文件后,我们无需知道文件的路径,只需要使用一个指向资源文件中的文件的URL就可以了。同时,资源文件可以编译到二进制程序中,这样资源文件就可以与二进制文件一起分发了,非常的方便。
示例如下:
// MyApp.qrc
&!DOCTYPE RCC&
&RCC version=&1.0&&
&qresource& &file&qml/main.qml&/file& &/qresource&
// MyObject.cpp
MyObject::MyObject() {
component = new QDeclarativeComponent(engine,
QUrl(&qrc:/qml/main.qml&));
if(!component-&isError()){
QObject* myObject = component-&create();
source: &images/background.png&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4300次
排名:千里之外
原创:27篇
(3)(9)(17)QML我们如何与C++一起使用_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
QML我们如何与C++一起使用
上传于|0|0|文档简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩11页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢1048人阅读
移动开发(263)
QML(182)
在先前的文章""中,我们介绍了如何利用Qt C++创建一个,并是我们的C++数据能够在我们的QML应用中呈现.在今天的文章中,我们将继续探讨这个话题.我们将利用另外一种方法来实现同样的目的.在今天的例程中,我们将展示如何从网路得到数据,并解析数据,进而在我们的QML应用中展示得到的数据.这个例程可以作为一个标准的例程供以后我们需要使用Qt
C++来作为数据的来源的时候使用.
为了能够在我们的QML应用中很好地使用C++,我们采用了我们SDK提供的"QtQuick App with QML UI (qmake)".
我们创建一个叫做"baiduweather"的应用.我们想利用我们的百度提供的API接口:
来得到我们的数据.具体的数据结果如下:
&error&: 0,
&status&: &success&,
&date&: &&,
&results&: [
&currentCity&: &北京&,
&pm25&: &25&,
&index&: [
&title&: &穿衣&,
&zs&: &热&,
&tipt&: &穿衣指数&,
&des&: &天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。&
&title&: &洗车&,
&zs&: &较适宜&,
&tipt&: &洗车指数&,
&des&: &较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少能保持一天。&
&title&: &旅游&,
&zs&: &适宜&,
&tipt&: &旅游指数&,
&des&: &天气较好,风稍大,但温度适宜,是个好天气哦。适宜旅游,您可以尽情地享受大自然的无限风光。&
&title&: &感冒&,
&zs&: &少发&,
&tipt&: &感冒指数&,
&des&: &各项气象条件适宜,无明显降温过程,发生感冒机率较低。&
&title&: &运动&,
&zs&: &较适宜&,
&tipt&: &运动指数&,
&des&: &天气较好,但风力较大,推荐您进行室内运动,若在户外运动请注意避风保暖。&
&title&: &紫外线强度&,
&zs&: &强&,
&tipt&: &紫外线强度指数&,
&des&: &紫外线辐射强,建议涂擦SPF20左右、PA++的防晒护肤品。避免在10点至14点暴露于日光下。&
&weather_data&: [
&date&: &周五 09月25日 (实时:25℃)&,
&dayPictureUrl&: &http://api./images/weather/day/qing.png&,
&nightPictureUrl&: &http://api./images/weather/night/qing.png&,
&weather&: &晴&,
&wind&: &北风3-4级&,
&temperature&: &27 ~ 13℃&
&date&: &周六&,
&dayPictureUrl&: &http://api./images/weather/day/qing.png&,
&nightPictureUrl&: &http://api./images/weather/night/duoyun.png&,
&weather&: &晴转多云&,
&wind&: &微风&,
&temperature&: &26 ~ 15℃&
&date&: &周日&,
&dayPictureUrl&: &http://api./images/weather/day/duoyun.png&,
&nightPictureUrl&: &http://api./images/weather/night/yin.png&,
&weather&: &多云转阴&,
&wind&: &微风&,
&temperature&: &26 ~ 16℃&
&date&: &周一&,
&dayPictureUrl&: &http://api./images/weather/day/yin.png&,
&nightPictureUrl&: &http://api./images/weather/night/duoyun.png&,
&weather&: &阴转多云&,
&wind&: &微风&,
&temperature&: &22 ~ 15℃&
从上面的数据结构中,我们可以定义如下的相应的C++类:
#ifndef WEATHERDATA_H
#define WEATHERDATA_H
#include &QObject&
class WeatherData : public QObject {
Q_PROPERTY(QString date
READ date WRITE setDate
NOTIFY dataChanged)
Q_PROPERTY(QString dayPictureUrl
READ dayPictureUrl WRITE setDayPictureUrl
NOTIFY dataChanged)
Q_PROPERTY(QString nightPictureUrl
READ nightPictureUrl WRITE setNightPictureUrl
NOTIFY dataChanged)
Q_PROPERTY(QString weather
READ weather WRITE setWeather
NOTIFY dataChanged)
Q_PROPERTY(QString wind
READ wind WRITE setWind
NOTIFY dataChanged)
Q_PROPERTY(QString temp
READ temp WRITE setTemp
NOTIFY dataChanged)
explicit WeatherData(QObject *parent = 0);
WeatherData(const WeatherData &other);
QString date()
QString dayPictureUrl()
QString nightPictureUrl()
QString weather()
QString wind()
QString temp()
void setDate(const QString &value);
void setDayPictureUrl(const QString &value);
void setNightPictureUrl(const QString &value);
void setWeather(const QString &value);
void setWind(const QString &value);
void setTemp(const QString &value);
void dataChanged();
QString m_
QString m_dayPictureU
QString m_nightPictureU
QString m_
QString m_
QString m_
Q_DECLARE_METATYPE(WeatherData)
#endif // WEATHERDATA_H
这个数据结构相应于我们JSON数据中"weather_data"数据结果.我们把每个数据都设为property,这样可以在QML中进行直接的读写.
这里的每个property的写法,就像如下的:
QString WeatherData::date() const
void WeatherData::setDate(const QString &value)
if ( m_date == value )
emit dataChanged();
这也是最标准的property的写法.
下面我们来看看appmodel.h的写法.
appmodel.h
#ifndef APPMODEL_H
#define APPMODEL_H
#include &QObject&
#include &QGeoPositionInfo&
#include &QGeoPositionInfoSource&
#include &QQmlListProperty&
class AppModelP
class WeatherD
class AppModel : public QObject
Q_PROPERTY(bool ready
READ ready
NOTIFY readyChanged)
Q_PROPERTY(QQmlListProperty&WeatherData& forecast
READ forecast
NOTIFY weatherChanged)
Q_PROPERTY(QString city
READ city WRITE setCity
NOTIFY cityChanged)
Q_PROPERTY(QString pm25
READ pm25 WRITE setCity
NOTIFY pm25Changed)
explicit AppModel(QObject *parent = 0);
bool ready()
QQmlListProperty&WeatherData& forecast()
QString city()
void setCity(const QString &value);
QString pm25()
void setPm25(const QString &value);
private slots:
void handleWeatherNetworkData(QObject *replyObj);
void handleGeoNetworkData(QObject *replyObj);
void networkSessionOpened();
void positionUpdated(QGeoPositionInfo gpsPos);
void positionError(QGeoPositionInfoSource::Error e);
void queryCity();
public slots:
Q_INVOKABLE void refreshWeather();
void readyChanged();
void cityChanged();
void pm25Changed();
void weatherChanged();
void hadError(bool tryAgain);
AppModelPrivate *d;
#endif // APPMODEL_H
这里沿袭了上面WeatherData中对property的写法,但是有一点不同的是,我们这里有一个比较特殊的property:
Q_PROPERTY(QQmlListProperty&WeatherData& forecast
READ forecast
NOTIFY weatherChanged)
这里的property是一个叫做.它里面的每个数据是WeatherData这个类型的,这个List的数据可以直接被我们的ListView或其它需要Model的UI对象所使用.在它们里面,我们可以直接使用它里面的WeatherData中的property.这也是和我们在先前文章""中所采用的方法不同的地方.当然我们也可以使用先前的的方法来重构我们的Model数据并被QML界面所使用.
在上面的AppModel定义中,我们也看见了一个叫做AppModelPrivate的类的使用.它的定义如下:
class AppModelPrivate
static const int baseMsBeforeNewRequest = 5 * 1000; // 5 s, increased after each missing answer up to 10x
QGeoPositionInfoSource *
QString longitude,
QNetworkAccessManager *
QNetworkSession *
QList&WeatherData*&
QQmlListProperty&WeatherData& *fcP
QSignalMapper *geoReplyM
QSignalMapper *weatherReplyM
bool hasValidC
int minMsBeforeNewR
QTimer delayedCityRequestT
QString pm25;
AppModelPrivate() :
src(NULL),
nam(NULL),
fcProp(NULL),
ready(false),
useGps(true),
hasValidCity(false),
nErrors(0),
minMsBeforeNewRequest(baseMsBeforeNewRequest),
delayedCityRequestTimer.setSingleShot(true);
delayedCityRequestTimer.setInterval(1000); // 1 s
throttle.invalidate();
这在移植Qt时,是一个标准的写法.通常这个类不是继承于QObject的.在这个标准的写法,其实也是需要把AppModel这个类的q(继承于QObject)指针传人到我们的Private类中.这样做的目的是为了能够利用我们的q指针来发送我们的信号,从而使得我们的UI或其它的QObject类能够收到Private类中的数据.有关于这个话题的更进一步资料,可以详细参阅Qt porting之类的文章.这里不一一描述了.这个类可以使用已有的平台的API来获取我们所需要的服务中的数据.
在AppModel类的实现中,我们把我们从网路中得到的数据,进行组装.有些我们可以直接通过AppModel的property进行访问.对于我们关心的天气预报的数据(是一个数组)我们通过上面讲到的QQmlListProperty提供给QML来访问:
void AppModel::handleWeatherNetworkData(QObject *replyObj)
qDebug() && &handleWeatherNetworkData&;
qDebug() && &got weather network data&;
QNetworkReply *networkReply = qobject_cast&QNetworkReply*&(replyObj);
if (!networkReply)
if (!networkReply-&error()) {
// We need to clear the previously stored data
QJsonDocument document = QJsonDocument::fromJson(networkReply-&readAll());
qDebug() && &document: & &&
QVariantMap root = document.toVariant().toMap();
QString date = root[&date&].toString();
qDebug() && &date: & &&
QList&QVariant& list = root[&results&].toList();
int count = list.count();
for (int i = 0; i & i++ ) {
QVariantMap item = list.at(i).toMap() ;
QString city = item[&currentCity&].toString();
qDebug() && &city: & &&
QString pm25 = item[&pm25&].toString();
qDebug() && &PM25: & && pm25;
QList&QVariant& index = item[&index&].toList();
int size = index.count();
qDebug() && &size: & &&
for ( int j = 0; j & j ++ ) {
QVariantMap each = index.at(j).toMap() ;
QString title = each[&title&].toString();
qDebug() && &title: & &&
QString des = each[&des&].toString();
qDebug() && &des: & &&
d-&forecast.clear();
foreach (const QVariant &k, item[&weather_data&].toList()) {
QVariantMap each = k.toMap();
QString date = each[&date&].toString();
qDebug() && &date: & && date && & length: & && date.length();
date = date.left(2);
qDebug() && &new date: & &&
QString dayPictureUrl = each[&dayPictureUrl&].toString();
qDebug() && &dayPictureUrl: & && dayPictureU
QString nightPictureUrl = each[&nightPictureUrl&].toString();
qDebug() && &nightPictureUrl: & && nightPictureU
QString weather = each[&weather&].toString();
qDebug() && &weather: & &&
QString wind = each[&wind&].toString();
qDebug() && &wind: & &&
QString temperature = each[&temperature&].toString();
qDebug() && &temperature: & &&
// Now let's fill in the weather data
WeatherData *forecastEntry = new WeatherData();
forecastEntry-&setDate(date);
forecastEntry-&setDayPictureUrl(dayPictureUrl);
forecastEntry-&setNightPictureUrl(nightPictureUrl);
forecastEntry-&setWeather(weather);
forecastEntry-&setWind(wind);
forecastEntry-&setTemp(temperature);
d-&forecast.append(forecastEntry);
if (!(d-&ready)) {
d-&ready =
emit readyChanged();
emit weatherChanged();
networkReply-&deleteLater();
为了能够使得我们的AppModel能被我们的QML正确地使用,我们必须要对它进行注册:
#include &QGuiApplication&
#include &QQmlApplicationEngine&
#include &QQuickView&
#include &appmodel.h&
#include &weatherdata.h&
int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
qmlRegisterType&WeatherData&(&WeatherInfo&, 1, 0, &WeatherData&);
qmlRegisterType&AppModel&(&WeatherInfo&, 1, 0, &AppModel&);
view.setSource(QUrl(QStringLiteral(&qrc:///Main.qml&)));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
相比较我们的AppModel来说,QML UI设计较为直接.我们直接来展示怎么实现的:
import QtQuick 2.0
ponents 1.1
import WeatherInfo 1.0
\brief MainView with a Label and Button elements.
MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: &mainView&
// Note! applicationName needs to match the &name& field of the click manifest
applicationName: &baiduweather.liu-xiao-guo&
This property enables the application to change orientation
when the device is rotated. The default is false.
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(60)
height: units.gu(85)
AppModel {
id: mymodel
onReadyChanged: {
console.log(&ready is changed!&);
console.log(&city: & + city)
console.log(&forecast[0]: & + forecast[0].dayPictureUrl);
if (mymodel.ready) {
page.state = &ready&
input.text = mymodel.city
listview.model = mymodel.
page.state = &loading&
// We cannot name it window.
title: i18n.tr(&Baidu Weather&)
anchors.fill: parent
spacing: units.gu(1)
TextField {
anchors.horizontalCenter: parent.horizontalCenter
onAccepted: {
mymodel.city =
onTextChanged: {
mymodel.city =
height: parent.height/3
width: height
anchors.horizontalCenter: parent.horizontalCenter
if ( !mymodel.ready )
var date = new Date();
var n = date.getHours();
if ( n &= 7 && n & 18 ) {
return mymodel.forecast[0].dayPictureU
return mymodel.forecast[0].nightPictureU
anchors.horizontalCenter: parent.horizontalCenter
text: mymodel.city
fontSize: &large&
anchors.horizontalCenter: parent.horizontalCenter
anchors.top:city.bottom
anchors.bottomMargin: units.gu(1)
text: &PM25: & + mymodel.pm25;
fontSize: &large&
id: firstrow
spacing: units.gu(1)
width: parent.width
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: mymodel.forecast
width: page.width
anchors.horizontalCenter: parent.horizontalCenter
spacing: units.gu(2)
anchors.horizontalCenter: parent.horizontalCenter
text: date
font.pixelSize: units.gu(3)
anchors.horizontalCenter: parent.horizontalCenter
width: (page.width - firstrow.spacing*3 ) /4
height: width
source: dayPictureUrl
anchors.horizontalCenter: parent.horizontalCenter
width: (page.width - firstrow.spacing*3) /4
height: width
source: nightPictureUrl
anchors.horizontalCenter: parent.horizontalCenter
text: mymodel.forecast[index].temp
在上面的设计中,我们使用了:
Repeater {
model: mymodel.forecast
     ....
来把我们的数据进行展示.当然,我们也可以选择ListView或其它的形式来完成.
运行我们的应用:
整个项目的源码在:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:351437次
积分:6954
积分:6954
排名:第2811名
原创:344篇
评论:244条
(6)(14)(10)(8)(9)(11)(4)(4)(3)(9)(6)(15)(8)(26)(4)(8)(1)(13)(6)(17)(18)(16)(23)(30)(16)(7)(2)(4)(8)(8)(11)(12)(18)

我要回帖

更多关于 甘薇的父亲是干什么的 的文章

 

随机推荐