您的位置:首页 > 娱乐 > 明星 > QML学习——Qt Quick Controls 1 Examples Calendar/FileSystemBrowser(九)

QML学习——Qt Quick Controls 1 Examples Calendar/FileSystemBrowser(九)

2025/3/14 1:19:04 来源:https://blog.csdn.net/Taiga_/article/details/140618057  浏览:    关键词:QML学习——Qt Quick Controls 1 Examples Calendar/FileSystemBrowser(九)
02 File System Browser

Show:

  • 演示

Notes:

  • 使用了自定义的继承自QFileSystemModel的类,在原有的基础上新加了角色(role),并且重写了QFileSystemModel中的data函数、及角色和字符串描述对应的哈希表;

  • 使用系统的文件资源管理器打开该文件的链接:Qt.openUrlExternally(url)

  • 关于QML的几种注册及属性:

    • qmlRegisterType方式注册:

      • 优点:

        1. QML 文件中可以直接使用注册的类型,创建其实例,并与其进行交互。
        2. 支持类型安全,QML 编辑器(如 Qt Creator)可以提供自动补全和类型检查。
        3. 适用于需要多个实例的情况,因为 QML 可以直接创建和管理这些实例。
      • 缺点:

        1. 需要 C++ 类与 QML 之间进行明确的类型匹配。
        2. 如果类具有复杂的构造函数或需要特定的初始化逻辑,可能需要额外的设置。
    • qmlRegisterUncreatableType注册一个C++类型:

      • 该类型不可实例化,但应可识别为QML类型系统的类型。
      • 如果类型的枚举或附加属性应该可以从QML访问,但是类型本身不应该是可实例化的,那么这很有用。
    • setContextProperty():将 C++ 对象或值设置为 QML 上下文的属性,这样 QML 文件中就可以通过属性名直接访问它。

      • 优点:
        1. 简单直接,适用于将单例或全局对象暴露给 QML。
        2. 不需要复杂的类型匹配或注册。
        3. 适用于需要多个实例的情况,因为 QML 可以直接创建和管理这些实例。
      • 缺点:
        1. 不支持类型安全,QML 编辑器可能无法提供自动补全或类型检查。
        2. 只能在 QML 文件中访问一个特定的实例(通常是单例)。
  • 关于Q_ENUM

    • This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.
    • In new code, you should prefer the use of the Q_ENUM() macro, which makes the type available also to the meta type system.
  • If the model is a string list or object list, the delegate is also exposed to a read-only modelData property that holds the string or object data.

  • Note: model, index, and modelData roles are not accessible if the delegate contains required properties, unless it has also required properties with matching names.

SourceCode:

  • TestCustomFileSystemBrowser.qml

  • import QtQuick 2.15
    import QtQuick.Controls 1.5
    import QtQml.Models 2.15import TestClasses.QC1.OfficialExample.CustomFileSystemModel 1.0Item {width: 640height: 480MenuBar {Menu {title: qsTr("File")MenuItem {text: qsTr("Exit")onTriggered: Qt.quit();}}}Row {id: row_IDanchors.top: parent.topanchors.topMargin: 12anchors.horizontalCenter: parent.horizontalCenterExclusiveGroup {id: eg}Repeater {model: [ "None", "Single", "Extended", "Multi", "Contig."]Button {//If the model is a string list or object list, the delegate is also exposed to a read-only modelData property that holds the string or object data.text: modelDataexclusiveGroup: egcheckable: truechecked: index === 1onClicked: view.selectionMode = index}}}ItemSelectionModel {id: selmodel: customFSysModel}TreeView {id: viewanchors.fill: parentanchors.margins: 2 * 12 + row_ID.heightmodel: customFSysModelrootIndex: rootPathIndexselection: selTableViewColumn {title: "Name"role: "fileName"resizable: true}TableViewColumn {title: "Size"role: "byteSize"resizable: truehorizontalAlignment : Text.AlignRightwidth: 70}TableViewColumn {title: "Permissions"role: "customFilePermissions"resizable: truewidth: 100}TableViewColumn {title: "Date Modified"role: "lastModified"resizable: true}onActivated : {var url = customFSysModel.data(index, CustomFSysModel.UrlStringRole)//使用系统的文件资源管理器打开该文件的链接Qt.openUrlExternally(url)}}
    }
    
  • customFileSystemModel.h

  • #ifndef CUSTOMFILESYSTEMMODEL_H
    #define CUSTOMFILESYSTEMMODEL_H#include <QFileSystemModel>
    #include <QObject>class CustomFileSystemModel : public QFileSystemModel
    {Q_OBJECT
    public:explicit CustomFileSystemModel(QObject *parent = nullptr);//自定义角色enum Roles  {SizeRole = ((Qt::UserRole + 3 == QFileSystemModel::FilePermissions) ? (Qt::UserRole + 4) : (QFileSystemModel::FilePathRole + 1)), //0x0104CustomFilePermissionsRole,LastModifiedRole,UrlStringRole};//This function is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code.//In new code, you should prefer the use of the Q_ENUM() macro, which makes the type available also to the meta type system.Q_ENUM(Roles)// QAbstractItemModel interface
    public://重写QFileSystemModel中的data函数QVariant data(const QModelIndex &index, int role) const override;//重写QAbstractItemModel中的roleNames函数QHash<int, QByteArray> roleNames() const override;
    };//file permissions:static inline QString permissionString(const QFileInfo &fi)
    {const QFile::Permissions permissions = fi.permissions();QString result = QLatin1String("----------");if (fi.isSymLink()) {result[0] = QLatin1Char('l');} else if (fi.isDir()) {result[0] = QLatin1Char('d');} else {result[0] = QLatin1Char('-');}if (permissions & QFileDevice::ReadUser)result[1] = QLatin1Char('r');if (permissions & QFileDevice::WriteUser)result[2] = QLatin1Char('w');if (permissions & QFileDevice::ExeUser)result[3] = QLatin1Char('x');if (permissions & QFileDevice::ReadGroup)result[4] = QLatin1Char('r');if (permissions & QFileDevice::WriteGroup)result[5] = QLatin1Char('w');if (permissions & QFileDevice::ExeGroup)result[6] = QLatin1Char('x');if (permissions & QFileDevice::ReadOther)result[7] = QLatin1Char('r');if (permissions & QFileDevice::WriteOther)result[8] = QLatin1Char('w');if (permissions & QFileDevice::ExeOther)result[9] = QLatin1Char('x');return result;
    }//human readable file size:
    static inline QString sizeString(const QFileInfo &fi)
    {if (!fi.isFile())return QString();const qint64 size = fi.size();if (size > static_cast<qint64>(1024) * 1024 * 1024 * 10)return QString::number(size / (1024 * 1024 * 1024)) + QLatin1Char('G');if (size > 1024 * 1024 * 10)return QString::number(size / (1024 * 1024)) + QLatin1Char('M');if (size > 1024 * 10)return QString::number(size / 1024) + QLatin1Char('K');return QString::number(size) + QLatin1Char('B');
    }#endif // CUSTOMFILESYSTEMMODEL_H
    
  • customFileSystemModel.cpp

  • #include "customFileSystemModel.h"#include <QLocale>
    #include <QUrl>
    #include <QDateTime>CustomFileSystemModel::CustomFileSystemModel(QObject *parent) : QFileSystemModel(parent)
    {}//重写QFileSystemModel中的data函数
    QVariant CustomFileSystemModel::data(const QModelIndex &index, int role) const
    {//自定义数据if (index.isValid() && role >= SizeRole) {switch (role) {case SizeRole:return QVariant(sizeString(fileInfo(index)));case CustomFilePermissionsRole:return QVariant(permissionString(fileInfo(index)));case LastModifiedRole:return QVariant(QLocale::system().toString(fileInfo(index).lastModified(), QLocale::ShortFormat)); //根据本地系统时间的短格式来设定最后修改时间样式case UrlStringRole:return QVariant(QUrl::fromLocalFile(filePath(index)).toString());default:break;}}//原始数据return QFileSystemModel::data(index, role);
    }//Returns the model's names. //QML Role Name
    QHash<int, QByteArray> CustomFileSystemModel::roleNames() const
    {//原有的角色名字QHash<int, QByteArray> result = QFileSystemModel::roleNames();result.insert(SizeRole, QByteArrayLiteral("byteSize"));result.insert(CustomFilePermissionsRole, QByteArrayLiteral("customFilePermissions"));result.insert(LastModifiedRole, QByteArrayLiteral("lastModified"));return result;
    }
    
01 Calendar

在这里插入图片描述

  • 本地数据库存储数据

  • SQL语句

  • event.h

  • #ifndef EVENT_H
    #define EVENT_H#include <QDateTime>
    #include <QObject>
    #include <QString>class Event : public QObject
    {Q_OBJECTQ_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)Q_PROPERTY(QDateTime startDate READ startDate WRITE setStartDate NOTIFY startDateChanged)Q_PROPERTY(QDateTime endDate READ endDate WRITE setEndDate NOTIFY endDateChanged)
    public:explicit Event(QObject *parent = 0);QString name() const;void setName(const QString &name);QDateTime startDate() const;void setStartDate(const QDateTime &startDate);QDateTime endDate() const;void setEndDate(const QDateTime &endDate);
    signals:void nameChanged(const QString &name);void startDateChanged(const QDateTime &startDate);void endDateChanged(const QDateTime &endDate);
    private:QString mName;QDateTime mStartDate;QDateTime mEndDate;
    };#endif
    
  • event.cpp

  • #include "event.h"Event::Event(QObject *parent) :QObject(parent)
    {
    }QString Event::name() const
    {return mName;
    }void Event::setName(const QString &name)
    {if (name != mName) {mName = name;emit nameChanged(mName);}
    }QDateTime Event::startDate() const
    {return mStartDate;
    }void Event::setStartDate(const QDateTime &startDate)
    {if (startDate != mStartDate) {mStartDate = startDate;emit startDateChanged(mStartDate);}
    }QDateTime Event::endDate() const
    {return mEndDate;
    }void Event::setEndDate(const QDateTime &endDate)
    {if (endDate != mEndDate) {mEndDate = endDate;emit endDateChanged(mEndDate);}
    }
    
  • sqleventmodel.h

  • #ifndef SQLEVENTMODEL_H
    #define SQLEVENTMODEL_H#include <QList>
    #include <QObject>class SqlEventModel : public QObject
    {Q_OBJECTpublic:SqlEventModel();Q_INVOKABLE QList<QObject*> eventsForDate(const QDate &date);private:static void createConnection();
    };#endif
    
  • sqleventmodel.cpp

  • #include "sqleventmodel.h"
    #include "event.h"#include <QDebug>
    #include <QFileInfo>
    #include <QSqlError>
    #include <QSqlQuery>SqlEventModel::SqlEventModel()
    {createConnection();
    }QList<QObject*> SqlEventModel::eventsForDate(const QDate &date)
    {const QString queryStr = QString::fromLatin1("SELECT * FROM Event WHERE '%1' >= startDate AND '%1' <= endDate").arg(date.toString("yyyy-MM-dd"));QSqlQuery query(queryStr);if (!query.exec())qFatal("Query failed");QList<QObject*> events;while (query.next()) {Event *event = new Event(this);event->setName(query.value("name").toString());QDateTime startDate;startDate.setDate(query.value("startDate").toDate());startDate.setTime(QTime(0, 0).addSecs(query.value("startTime").toInt()));event->setStartDate(startDate);QDateTime endDate;endDate.setDate(query.value("endDate").toDate());endDate.setTime(QTime(0, 0).addSecs(query.value("endTime").toInt()));event->setEndDate(endDate);events.append(event);}return events;
    }/*Defines a helper function to open a connection to anin-memory SQLITE database and to create a test table.
    */
    void SqlEventModel::createConnection()
    {//SQLite version 3 or above//defalut connectionNameQSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(":memory:"); //based on memoryif (!db.open()) {qFatal("Cannot open database");return;}QSqlQuery query;// We store the time as seconds because it's easier to query.query.exec("create table Event (name TEXT, startDate DATE, startTime INT, endDate DATE, endTime INT)");query.exec("insert into Event values('Grocery shopping', '2014-01-01', 36000, '2014-01-01', 39600)");query.exec("insert into Event values('Ice skating', '2014-01-01', 57600, '2014-01-01', 61200)");query.exec("insert into Event values('Doctor''s appointment', '2014-01-15', 57600, '2014-01-15', 63000)");query.exec("insert into Event values('Conference', '2014-01-24', 32400, '2014-01-28', 61200)");return;
    }
    
  • TestQC1Calendar.qml

  • import QtQuick 2.15
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    import QtQuick.Controls.Private 1.0import TestClasses.QC1.OfficialExampleCalendar 1.0Rectangle {width: 640height: 400color: "#f4f4f4"SystemPalette {id: systemPalette}SqlEventModel {id: eventModel}Flow {id: rowanchors.fill: parentanchors.margins: 20spacing: 10layoutDirection: Qt.RightToLeftCalendar {id: calendarwidth: (parent.width > parent.height ? parent.width * 0.6 - parent.spacing : parent.width)height: (parent.height > parent.width ? parent.height * 0.6 - parent.spacing : parent.height)frameVisible: trueweekNumbersVisible: trueselectedDate: new Date(2014, 0, 1)focus: truestyle: CalendarStyle {dayDelegate: Item {readonly property color sameMonthDateTextColor: "#444"readonly property color selectedDateColor: Qt.platform.os === "osx" ? "#3778d0" : systemPalette.highlightreadonly property color selectedDateTextColor: "white"readonly property color differentMonthDateTextColor: "#bbb"readonly property color invalidDatecolor: "#dddddd"Rectangle {anchors.fill: parentborder.color: "transparent"color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "transparent"anchors.margins: styleData.selected ? -1 : 0}Image {visible: eventModel.eventsForDate(styleData.date).length > 0anchors.top: parent.topanchors.left: parent.leftanchors.margins: -1width: 12height: widthsource: "qrc:/Icons/Used_Images/Icons/10_12used_QC1Calendar_Pinned.png"}Label {id: dayDelegateTexttext: styleData.date.getDate()anchors.centerIn: parentcolor: {var color = invalidDatecolor;if (styleData.valid) {// Date is within the valid range.color = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor;if (styleData.selected) {color = selectedDateTextColor;}}color;}}}}}Component {id: eventListHeaderRow {id: eventDateRowwidth: parent.widthheight: eventDayLabel.heightspacing: 10Label {id: eventDayLabeltext: calendar.selectedDate.getDate()font.pointSize: 35}Column {height: eventDayLabel.heightLabel {readonly property var options: { weekday: "long" }text: Qt.locale().standaloneDayName(calendar.selectedDate.getDay(), Locale.LongFormat)font.pointSize: 18}Label {text: Qt.locale().standaloneMonthName(calendar.selectedDate.getMonth())+ calendar.selectedDate.toLocaleDateString(Qt.locale(), " yyyy")font.pointSize: 12}}}}Rectangle {width: (parent.width > parent.height ? parent.width * 0.4 - parent.spacing : parent.width)height: (parent.height > parent.width ? parent.height * 0.4 - parent.spacing : parent.height)border.color: Qt.darker(color, 1.2)ListView {id: eventsListViewspacing: 4clip: trueheader: eventListHeaderanchors.fill: parentanchors.margins: 10model: eventModel.eventsForDate(calendar.selectedDate)delegate: Rectangle {width: eventsListView.widthheight: eventItemColumn.heightanchors.horizontalCenter: parent.horizontalCenterImage {anchors.top: parent.topanchors.topMargin: 4width: 12height: widthsource: "qrc:/Icons/Used_Images/Icons/10_12used_QC1Calendar_Pinned.png"}Rectangle {width: parent.widthheight: 1color: "#eee"}Column {id: eventItemColumnanchors.left: parent.leftanchors.leftMargin: 20anchors.right: parent.rightheight: timeLabel.height + nameLabel.height + 8Label {id: nameLabelwidth: parent.widthwrapMode: Text.Wraptext: modelData.name}Label {id: timeLabelwidth: parent.widthwrapMode: Text.Wraptext: modelData.startDate.toLocaleTimeString(calendar.locale, Locale.ShortFormat)color: "#aaa"}}}}}}
    }
    

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com