Qt 示例学习--1. enginio qml todos

来源:互联网 发布:bat软件测试招聘 编辑:程序博客网 时间:2024/05/22 12:16

起因

由于非正规计算机专业毕业,缺乏系统的计算机知识学习,虽然课余也自己进行补充学习,但一味地学习而不实践往往记忆较为肤浅,于是想通过一些不断地训练提高自己的编程技能。寻找后发现Qt自带的例子都比较简短却能够突出很多知识点,遂进行学习:

开始学习

从第一个开始选择enginio qml todos

分析该示例作用:

主要是帮助学习qml的使用并搭配enginio的使用。enginio使用先忽略,牵涉到的比较少,具体用到再细细分析。

分析主程序:

int main(int argc, char* argv[]){    QGuiApplication app(argc,argv);    QQuickView view;    const QString appPath = QCoreApplication::applicationDirPath();    // This allows starting the example without previously defining QML2_IMPORT_PATH.    QDir qmlImportDir(appPath);#if defined (Q_OS_WIN)    qmlImportDir.cd("..");#endif    qmlImportDir.cd("../../../qml");    view.engine()->addImportPath(qmlImportDir.canonicalPath());    QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));    BackendHelperContext *backendContext = new BackendHelperContext(&view);    view.engine()->rootContext()->setContextProperty("enginioBackendContext", backendContext);    view.setSource(QUrl("qrc:///" ENGINIO_SAMPLE_NAME ".qml"));    view.setResizeMode(QQuickView::SizeRootObjectToView);    view.show();    return app.exec();}

1.main函数和以往通过Qt默认生成的Qt Widget Application有些不同:

int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    w.show();    return a.exec();}

可见,例子中使用的是QGuiApplication和QQuickView。
查看帮助文档可知:

For any GUI application using Qt, there is precisely one QGuiApplication object no matter whether the application has 0, 1, 2 or more windows at any given time. For non-GUI Qt applications, use QCoreApplication instead, as it does not depend on the Qt GUI module. For QWidget based Qt applications, use QApplication instead, as it provides some functionality needed for creating QWidget instances.

意思是说,gui程序需要使用QGuiApplication,非gui程序可以使用QCoreApplication 而QWidget需要使用QApplication。

2.QQuickView:

查看帮助可以知道典型的使用方法如下:

QQuickView *view = new QQuickView;
view->setSource(QUrl::fromLocalFile(“myqmlfile.qml”));
view->show();

注意下面一句:

view.engine()->rootContext()->setContextProperty(“enginioBackendContext”, backendContext);

将enginioBackendContext的内容设置为backendContext;enginioBackendContext将在qml中进行使用:
搜索enginioBackendContext内容

3.注意view.setSource(QUrl(“qrc:///” ENGINIO_SAMPLE_NAME “.qml”));中ENGINIO_SAMPLE_NAME并没有在源文件中找到,再次搜索:

搜索ENGINIO_SAMPLE_NAME内容
原来,这里是在pro文件中定义的宏。

4.分析BackendHelperContext:

class BackendHelperContext : public QObject{    Q_OBJECT    Q_PROPERTY(QString exampleName READ exampleName CONSTANT)    Q_PROPERTY(QString backendId READ backendId WRITE setBackendId NOTIFY backendIdChanged)    QString _backendId;    QScopedPointer<QSettings> _settings;    static QString _exampleName;public:    BackendHelperContext(QQuickView *parent)        : QObject(parent)    {        QString fileName = QStringLiteral("EnginioExamples.conf");        for (int i = 0; i < 4; ++i) {            if (QFile::exists(fileName))                break;            fileName = fileName.prepend("../");        }        QFileInfo settingsFile = QFileInfo(fileName);        _settings.reset(settingsFile.exists()            ? new QSettings(settingsFile.absoluteFilePath(), QSettings::IniFormat)            : new QSettings("QtProject", "EnginioExamples"));        _settings->beginGroup(_exampleName);        _backendId = _settings->value(backendIdKey).toString();    }    ~BackendHelperContext()    {        _settings->endGroup();        _settings->sync();    }    QString backendId() const { return _backendId; }    void setBackendId(const QString &backendId)    {        if (_backendId == backendId)            return;        _backendId = backendId;        _settings->setValue(backendIdKey, _backendId);        emit backendIdChanged();    }    QString exampleName() const { return _exampleName; }signals:    void backendIdChanged();};

4.1 Q_OBJECT 用于Qt自省机智的宏

4.2 Q_PROPERTY(QString exampleName READ exampleName CONSTANT)

该宏用于声明一个该QObject的属性(即一个成员变量,虽然直接自己声明一个成员变量有些情况也可行,但是唯有通过此方法才能将该属性添加到该QOBject的自省机制中···)。
具体使用还是比较简单的,详细用法可以参照Qt自带帮助。
以上声明的含义是:BackendHelperContext 有一个私有变量exampleName ,并需要提供一个QString exampleName () const;成员函数。
Q_PROPERTY(QString backendId READ backendId WRITE setBackendId NOTIFY backendIdChanged) 表示:有一个QString backendId;变量,并提供了read和write函数,以及当该变量发生变化的时候会触发backendIdChanged信号。
A NOTIFY signal is optional. If defined, it should specify one existing signal in that class that is emitted whenever the value of the property changes.
附示例实现代码,发现设置NOTIFY 后,需要在设置函数中手动发出指定信号。
void setBackendId(const QString &backendId)
{
if (_backendId == backendId)
return;
_backendId = backendId;
_settings->setValue(backendIdKey, _backendId);
emit backendIdChanged();
}

4.3 QScopedPointer _settings;

这是一个Qt中的智能指针,可用于自动回收new出的指针。

4.4 QString fileName = QStringLiteral(“EnginioExamples.conf”);

看到一个QStringLiteral

The macro generates the data for a QString out of str at compile time if the compiler supports it. Creating a QString from it is free in this case, and the generated string data is stored in the read-only segment of the compiled object file.
For compilers not supporting the creation of compile time strings, QStringLiteral will fall back to QString::fromUtf8().

看帮助可以知道,QStringLiteral在支持创建编译期string的情况下可以创建QString指向指针常量。

5.看下pro文件:

TEMPLATE = app
DEFINES += ENGINIO_SAMPLE_NAME=\\”todo\\”
include(../../common/backendhelper/qmlbackendhelper.pri)
QT += quick qml enginio
SOURCES += ../main.cpp
mac: CONFIG -= app_bundle
OTHER_FILES += todo.qml
RESOURCES += todo.qrc

注意到:QT 用到了quick qml enginio三个模块,前两个用于quick的,后面一个用于云端开发,以后用到再深入了解。

6.了解qml

讲讲主要的界面(屏蔽了开始的一个界面):
主要界面
全部代码摘抄有些多大体写下:

Item {    Rectangle {        EnginioModel  // model        Rectangle     // 上面的长条形区域        ListView      // list区域        BorderImage   // 下侧区域,BorderImage有些类似于android中的.9图片        Component {   // Delegate                id: listItemDelegate        }    }}
0 0
原创粉丝点击