qml学习----------------(progressBar)进度条的学习

这篇博客介绍了Qt QML中进度条ProgressBar的学习过程,包括其主要属性如hovered、indeterminate、maximumValue等,并强调了通过style属性自定义进度条样式的方法,如设置背景颜色、控制条风格等。博主分享了相关代码以加深理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天学习了进度条的使用。查了下qt的官方文档,进度条主要有以下的属性
hovered : bool
indeterminate : bool
maximumValue : real
minimumValue : real
orientation : int //决定是水平的还是竖直的
style : Component
value : real

可以通过style来加载一个progressBarStyle来确定进度条的风格
background : Component //背景颜色
control : ProgressBar //进度条
currentProgress : real //当前进度
panel : Component //这个用来加载 背景颜色 , 进度条等自定义组件的风格等
progress : Component

下面就看下代码来学习下:

import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2

Rectangle{

    width: 520;
    height: 280;
    color:"#a0b0c0";


    Row{

        anchors.fill:  parent;
        anchors.margins: 50;
        spacing: 8;



        //进度条1
        ProgressBar{

            minimumValue: 0;
            maximumValue: 100;
            value: 40;
            width: 150;
            height: 20;

            Timer{
                interval: 1000;
                repeat: true;
                running: true;
                onTriggered: {
                    if(parent.value < 99.1){
                        parent.value += 1;
                    }else{
                        stop();
                    }
                }

            }

        }

        //进度条2
        ProgressBar{
            orientation: Qt.Vertical; //设置竖直滚动条
            minimumValue: 0;
            maximumValue: 1;
            value: 0.2;
            width: 20;
            height: 200;
            Timer{

                interval: 1000;
                repeat: true;
                running: true;
                onTriggered: {
                    parent.value = Math.random();
                }
            }

        }


        //进度条3
        ProgressBar{

            minimumValue: 0;
            maximumValue: 1;
            value: 0.2;
            width: 80;
            height: 16;
            //当indeterminte设置为真实, ProcessBar变成了BusyIndicator了,请稍等,不久后就会告诉你答案
            indeterminate: true;
        }



        Item{
            width: 180;
            height: parent.height;

            //进度条4
            ProgressBar{

                id: customProgress;
                anchors.centerIn: parent;
                minimumValue: 0;
                maximumValue: 1;
                value: 0.2;
                width: 160;
                height: 20;

                style: ProgressBarStyle{
                    background: Rectangle{
                        implicitWidth: 200;
                        implicitHeight: 20;
                        border.width: 1;
                        border.color: control.hovered ? "green":"gray";
                        color:"lightgray";
                    }


                    progress: Rectangle{

                        color: "#208020";
                    }

                }

            }



            //进度条5
            ProgressBar{
                id: percentProcess;
                anchors.top: customProgress.bottom;
                anchors.topMargin: 4;
                anchors.horizontalCenter: parent.horizontalCenter;
                minimumValue: 0;
                maximumValue: 1;
                value: 0.33;
                width: 160;
                height: 20;

                style: ProgressBarStyle{
                    id: progressStyle;
                    background: Rectangle{
                        border.width: 1;
                        border.color: control.hovered?"green":"gray";
                        color:"lightgray";
                    }


                    progress: Rectangle{
                        color:"#208020";

                    }


                    panel: Item{

                        //通过panel属性,可以加载  progress Text background等组件

                        //设置外边框
                        implicitWidth: 200;
                        implicitHeight: 20;

                        Loader{
                            anchors.fill:  parent;
                            sourceComponent: background;
                        }


                        Loader{
                            id: progressLoader;
                            anchors.top: parent.top;
                            anchors.left: parent.left;
                            anchors.bottom:  parent.bottom;
                            anchors.margins: 3;
                            z: 1;
                            width: currentProgress * (parent.width - 6);
                            sourceComponent: progressStyle.progress;

                        }


                        Text{

                            color: "blue";
                            text:currentProgress * 100 + "%";
                            z: 2;
                            anchors.centerIn: parent;

                        }

                    }
                }

            }

        }

    }

}
<think>我们正在使用QtMvvm库实现自定义属性列表展示。根据之前的示例,我们定义了ViewModel和对应的数据类(Contact),并使用ListModel来管理列表数据。现在,用户的需求是展示具有自定义属性的列表。假设我们的数据类有多个属性,并且我们希望在QML中能够访问这些属性。回顾之前的步骤:1.定义数据类(例如Contact),使用Q_GADGET和Q_PROPERTY声明属性。2.在ViewModel中创建ListModel实例,并注册数据类。3.在ViewModel中提供操作列表的方法(如添加、删除等)。4.在QML中,通过ListModel的role名称(即数据类的属性名)来访问数据。为了展示自定义属性,我们只需要在数据类中增加相应的属性即可。示例扩展:假设我们除了name和phone外,还想增加一个自定义属性,如头像(avatar),类型为字符串(URL)。步骤:1.修改Contact类,增加avatar属性。2.在ViewModel的addContact方法中,添加avatar参数,并在添加数据时包含avatar。3.在QML视图中,使用新的属性。注意:由于ListModel会为数据类的每个属性创建角色,所以我们不需要额外设置。具体代码调整如下:</think> ### 使用 QtMVVM 实现自定义属性列表展示 以下是基于 QtMVVM 库实现自定义属性列表展示的完整方案: --- #### 1. 定义数据类(带自定义属性) ```cpp #include <QObject> #include <QUrl> class CustomItem : public QObject { Q_OBJECT Q_PROPERTY(QString title READ title CONSTANT) Q_PROPERTY(QString description READ description CONSTANT) Q_PROPERTY(int priority READ priority CONSTANT) Q_PROPERTY(QUrl imageUrl READ imageUrl CONSTANT) public: explicit CustomItem(QString title, QString description, int priority, QUrl imageUrl, QObject* parent = nullptr) : QObject(parent), _title(std::move(title)), _description(std::move(description)), _priority(priority), _imageUrl(std::move(imageUrl)) {} QString title() const { return _title; } QString description() const { return _description; } int priority() const { return _priority; } QUrl imageUrl() const { return _imageUrl; } private: QString _title; QString _description; int _priority; QUrl _imageUrl; }; // main.cpp 中注册元类型 Q_DECLARE_METATYPE(CustomItem*) ``` --- #### 2. 定义 ViewModel(管理列表数据) ```cpp #include <QtMvvmCore/ViewModel> #include <QtMvvmDataSync/ListModel> class CustomListViewModel : public QtMvvm::ViewModel { Q_OBJECT Q_PROPERTY(QtMvvm::ListModel* items READ items CONSTANT) public: explicit CustomListViewModel(QObject* parent = nullptr) : ViewModel(parent), _itemsModel(new QtMvvm::ListModel(this)) { // 注册数据类型 _itemsModel->registerType<CustomItem>(); // 添加示例数据 addItem("项目A", "高优先级任务", 1, QUrl("qrc:/icons/high.png")); addItem("项目B", "常规任务", 2, QUrl("qrc:/icons/normal.png")); } QtMvvm::ListModel* items() const { return _itemsModel; } Q_INVOKABLE void addItem(const QString& title, const QString& description, int priority, const QUrl& imageUrl) { _itemsModel->append(new CustomItem(title, description, priority, imageUrl)); } Q_INVOKABLE void removeItem(int index) { if (index >= 0 && index < _itemsModel->count()) { _itemsModel->remove(index); } } private: QtMvvm::ListModel* _itemsModel; }; ``` --- #### 3. QML 视图实现 ```qml import QtQuick 2.15 import QtQuick.Controls 2.15 import QtMvvm.Core 1.0 ApplicationWindow { width: 600 height: 800 visible: true property CustomListViewModel viewModel: ViewModelLoader { viewModelType: "CustomListViewModel" } ListView { anchors.fill: parent model: viewModel.items delegate: ItemDelegate { width: parent.width height: 100 Row { spacing: 20 anchors.fill: parent anchors.margins: 10 Image { source: model.imageUrl width: 80 height: 80 fillMode: Image.PreserveAspectFit } Column { width: parent.width - 140 spacing: 5 Label { text: model.title font.bold: true font.pixelSize: 18 } Label { text: model.description width: parent.width wrapMode: Text.Wrap } ProgressBar { value: 3 - model.priority // 优先级越高进度条越满 to: 2 width: parent.width } } Button { text: "删除" onClicked: viewModel.removeItem(model.index) } } } } } ``` --- #### 4. 注册 ViewModel(main.cpp) ```cpp #include <QtMvvmCore/ServiceRegistry> #include <QtMvvmCore/Settings> #include <QtMvvmCore/ViewModelRegister> int main(int argc, char *argv[]) { // 注册服务 QtMvvm::ServiceRegistry::registerObject<QtMvvm::Settings>(); // 注册ViewModel QtMvvm::ViewModelRegister::registerViewModel<CustomListViewModel>("CustomListViewModel"); // 启动应用 QtMvvm::QuickApp app(argc, argv); app.setAppDisplayName("自定义属性列表"); // 加载QML app.load(QUrl("qrc:/main.qml")); return app.exec(); } ``` --- ### 关键特性实现 #### 1. 自定义属性绑定 实现模型与视图的自动同步: $$ \text{数据变更} \rightarrow \text{ListModel} \xrightarrow{\text{信号}} \text{QML视图} $$ ```qml // QML中直接绑定自定义属性 Label { text: model.title color: model.priority === 1 ? "red" : "black" } ``` #### 2. 属性变更通知 在数据类中添加属性变更通知: ```cpp // 在CustomItem类中添加 Q_PROPERTY(int progress READ progress WRITE setProgress NOTIFY progressChanged) signals: void progressChanged(); ``` #### 3. 动态排序 ```cpp // 在ViewModel中添加排序方法 Q_INVOKABLE void sortByPriority() { _itemsModel->sort([](const QObject* a, const QObject* b) { auto itemA = qobject_cast<const CustomItem*>(a); auto itemB = qobject_cast<const CustomItem*>(b); return itemA->priority() < itemB->priority(); }); } ``` --- ### 性能优化建议 1. **分页加载** ```cpp _itemsModel->setChunkSize(20); // 每次加载20条 ``` 2. **异步加载** ```cpp QFuture<void> future = QtConcurrent::run([this]{ // 网络请求或数据库操作 _itemsModel->appendBatch(items); }); ``` 3. **角色选择** ```qml ListView { delegate: ItemDelegate { // 仅绑定实际使用的属性 text: model.title // 避免访问model.description等未使用的属性 } } ``` --- ### 常见问题解决 1. **属性未显示** - 检查 `Q_PROPERTY` 声明是否包含 `READ` 方法 - 确认 `registerType<CustomItem>()` 已调用 - 确保 QML 使用 `model.propertyName` 格式 2. **数据更新延迟** 在修改属性后手动触发刷新: ```cpp emit dataChanged(createIndex(row, 0), createIndex(row, 0)); ``` 3. **跨线程访问** 使用 `QMetaObject::invokeMethod` 进行线程安全的数据操作: ```cpp QMetaObject::invokeMethod(_itemsModel, "append", Qt::QueuedConnection, Q_ARG(QObject*, newItem)); ``` ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值