【QT】概述
个人主页:Guiat
归属专栏:QT
文章目录
- 1. Qt基础入门
- 1.1 什么是Qt
- 1.2 Qt的历史与发展
- 1.3 Qt的核心特性
- 2. Qt架构深度解析
- 3. Qt开发环境搭建
- 4. Qt应用开发实战
- 4.1 项目结构
- 4.2 设计用户界面
- 4.3 实现功能逻辑
- 4.4 数据持久化
- 4.5 美化界面
- 4.6 添加动画效果
- 5. Qt Quick与QML
- 5.1 QML基础语法
- 5.2 QML与JavaScript结合
- 5.3 QML的动态特性
正文
Qt,这个名字听起来像是"cute"的缩写,但实际上它是一个功能强大的跨平台应用程序开发框架。如果你曾经使用过VLC媒体播放器、Skype、或者某些Linux桌面环境,那么恭喜你,你已经体验过Qt的魅力了!今天我们就来深入了解这个让无数程序员又爱又恨的开发框架。
1. Qt基础入门
1.1 什么是Qt
Qt(发音为"cute")是一个跨平台的C++图形用户界面应用程序开发框架。它不仅仅是一个GUI库,更是一个完整的应用程序开发平台,包含了开发桌面、移动和嵌入式应用程序所需的一切工具。
想象一下,你要建造一座房子。传统的方式是你需要自己准备砖头、水泥、钢筋等各种材料,然后一点一点地搭建。而Qt就像是一个预制房屋套件,它为你提供了标准化的"墙壁"、“门窗”、"屋顶"等组件,你只需要按照说明书组装,就能快速建造出一座漂亮的房子。
【代码】
#include <QApplication>
#include <QLabel>int main(int argc, char *argv[])
{QApplication app(argc, argv);QLabel label("Hello, Qt World!");label.show();return app.exec();
}
【mermaid图】
【举例说明】
就像乐高积木一样,Qt提供了各种"积木块"(组件),你可以用这些积木块搭建出各种不同的"作品"(应用程序)。一个简单的文本编辑器可能只需要几个基础组件,而一个复杂的图像处理软件则需要更多高级组件的组合。
1.2 Qt的历史与发展
Qt的故事始于1991年,当时两个挪威程序员Haavard Nord和Eirik Chambe-Eng创立了Trolltech公司。他们的目标很简单:创建一个能够在不同操作系统上运行相同代码的GUI框架。这在当时是一个相当大胆的想法,因为那个年代的软件开发通常都是平台专用的。
Qt的发展历程就像一部精彩的商业传奇:
- 1995年:Qt 0.90发布,开始崭露头角
- 1998年:KDE桌面环境选择Qt作为基础框架
- 2008年:Nokia收购Trolltech,Qt进入移动时代
- 2012年:Qt项目转为开源治理模式
- 2014年:The Qt Company成立,专注Qt商业化
【代码】
// Qt 1.x 时代的代码风格
class MyWidget : public QWidget
{
public:MyWidget() {resize(200, 100);setCaption("Old Qt Style");}
};// 现代Qt的代码风格
class MyWidget : public QWidget
{Q_OBJECT
public:MyWidget(QWidget *parent = nullptr) : QWidget(parent) {setWindowTitle("Modern Qt Style");resize(200, 100);}
};
【mermaid图】
timelinetitle Qt发展历程1991 : Trolltech成立1995 : Qt 0.90发布1998 : KDE采用Qt2005 : Qt 4.0发布: 引入Graphics View2009 : Qt 4.6发布: 支持触摸和手势2011 : Qt 5.0发布: QML和Qt Quick2020 : Qt 6.0发布: C++17支持
【举例说明】
Qt的发展就像智能手机的进化史。最初的Qt就像第一代手机,功能简单但革命性;Qt 4时代像是功能手机的巅峰,稳定可靠;Qt 5时代则像智能手机的爆发期,引入了触摸、动画等现代特性;而Qt 6就像是5G时代的手机,性能更强,功能更丰富。
1.3 Qt的核心特性
Qt的魅力在于它的"一次编写,到处运行"理念。但这不仅仅是跨平台那么简单,Qt还有许多让开发者爱不释手的特性。
信号与槽机制
这是Qt最著名的特性之一,它提供了一种优雅的对象间通信方式。想象一下,你在餐厅点餐,你按下服务铃(信号),服务员就会过来(槽函数被调用)。这种机制让程序的各个部分能够松耦合地协作。
元对象系统
Qt的元对象系统为C++添加了反射能力,这让很多高级特性成为可能,比如属性系统、信号槽机制等。
丰富的组件库
从基础的按钮、文本框,到复杂的图表、3D渲染,Qt几乎提供了你能想到的所有UI组件。
【代码】
#include <QApplication>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QWidget>class CounterWidget : public QWidget
{Q_OBJECTprivate:QLabel *countLabel;QPushButton *incrementButton;int count = 0;public:CounterWidget(QWidget *parent = nullptr) : QWidget(parent) {// 创建组件countLabel = new QLabel("Count: 0");incrementButton = new QPushButton("Increment");// 布局QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(countLabel);layout->addWidget(incrementButton);// 连接信号和槽connect(incrementButton, &QPushButton::clicked, this, &CounterWidget::incrementCount);}private slots:void incrementCount() {count++;countLabel->setText(QString("Count: %1").arg(count));}
};
【mermaid图】
【举例说明】
Qt的信号槽机制就像现代智能家居系统。当你按下墙上的开关(信号发送者),灯泡就会亮起(信号接收者)。但神奇的是,你可以让一个开关控制多个设备,也可以让多个开关控制同一个设备,甚至可以设置复杂的联动逻辑。这种灵活性让程序设计变得非常优雅。
2. Qt架构深度解析
Qt的架构设计堪称软件工程的典范,它采用模块化设计,每个模块都有明确的职责和边界。理解Qt的架构就像理解一座现代化城市的规划,每个区域都有其特定的功能,但又通过完善的交通网络连接在一起。
Qt的核心架构可以分为几个层次:
基础层(Qt Core)
这是Qt的心脏,提供了非GUI的核心功能,包括对象模型、事件系统、文件I/O、字符串处理等。就像城市的基础设施,虽然你看不见,但一切都依赖于它。
GUI层(Qt GUI)
负责图形渲染、窗口管理、事件处理等与图形界面相关的底层功能。
组件层(Qt Widgets/Qt Quick)
提供高级的用户界面组件,Qt Widgets是传统的桌面组件,而Qt Quick则是现代的声明式UI框架。
【代码】
// Qt Core 示例:对象树和内存管理
#include <QObject>
#include <QTimer>
#include <QDebug>class Parent : public QObject
{Q_OBJECT
public:Parent() {// 创建子对象,Qt会自动管理内存QTimer *timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &Parent::onTimeout);timer->start(1000);qDebug() << "Parent created with timer";}~Parent() {qDebug() << "Parent destroyed, timer automatically deleted";}private slots:void onTimeout() {qDebug() << "Timer tick";}
};// Qt GUI 示例:自定义绘制
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>class CustomWidget : public QWidget
{Q_OBJECT
public:CustomWidget(QWidget *parent = nullptr) : QWidget(parent) {setMinimumSize(200, 200);}protected:void paintEvent(QPaintEvent *event) override {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 绘制渐变背景QLinearGradient gradient(0, 0, width(), height());gradient.setColorAt(0, QColor(100, 150, 255));gradient.setColorAt(1, QColor(255, 100, 150));painter.fillRect(rect(), gradient);// 绘制文字painter.setPen(Qt::white);painter.drawText(rect(), Qt::AlignCenter, "Custom Qt Widget");}
};
【mermaid图】
【举例说明】
Qt的架构就像一座摩天大楼。地基(Qt Core)提供了稳固的基础,包括电力、水管、网络等基础设施;中间层(Qt GUI)就像大楼的结构框架,定义了空间的基本形状;而顶层(Qt Widgets/Qt Quick)则是各种装修精美的办公室和商铺,直接面向用户。每一层都依赖于下层,但又为上层提供服务。
Qt的模块化设计让开发者可以根据需要选择合适的组件。开发一个简单的命令行工具?只需要Qt Core。开发桌面应用?加上Qt Widgets。需要现代化的动画效果?Qt Quick是你的选择。这种设计哲学让Qt既强大又灵活。
3. Qt开发环境搭建
工欲善其事,必先利其器。搭建一个高效的Qt开发环境就像装修一个舒适的工作室,每个工具都要放在合适的位置,这样才能提高开发效率。
Qt的开发环境主要包括以下几个组件:
- Qt库:核心的运行时库和开发库
- Qt Creator:官方集成开发环境(IDE)
- 编译器:如GCC、Clang或MSVC
- 调试器:如GDB或CDB
- Qt Designer:可视化界面设计工具
安装Qt有几种方式,最简单的是使用Qt官方提供的在线安装器。这个安装器就像一个智能管家,会根据你的需求推荐合适的组件。
【代码】
# Linux下编译Qt项目的典型流程
# 1. 生成Makefile
qmake MyProject.pro# 2. 编译项目
make# 3. 运行程序
./MyProject# 或者使用CMake(现代推荐方式)
mkdir build
cd build
cmake ..
make
./MyProject
# CMakeLists.txt 示例
cmake_minimum_required(VERSION 3.16)
project(MyQtApp)# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 查找Qt组件
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)# 启用Qt的MOC
set(CMAKE_AUTOMOC ON)# 添加可执行文件
add_executable(MyQtAppmain.cppmainwindow.cppmainwindow.h
)# 链接Qt库
target_link_libraries(MyQtApp Qt6::Core Qt6::Widgets)
【mermaid图】
【举例说明】
搭建Qt开发环境就像为你的厨房准备烹饪工具。你需要有合适的锅具(Qt库)、刀具(编译器)、食谱(Qt Creator),以及调料(调试器)来帮助你制作美味的菜肴(应用程序)。一旦一切准备就绪,你就可以开始烹饪,创造出美味的作品。
4. Qt应用开发实战
在了解了Qt的基础知识和开发环境后,接下来我们将通过一个简单的项目来实践Qt的开发。我们将创建一个基本的待办事项应用程序,帮助用户管理日常任务。
4.1 项目结构
我们的待办事项应用程序将包含以下几个主要组件:
- 主窗口:显示待办事项列表
- 输入框:用于输入新任务
- 添加按钮:添加新任务到列表
- 删除按钮:删除选中的任务
项目结构如下:
TodoApp/
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
└── mainwindow.ui
4.2 设计用户界面
我们将使用Qt Designer来设计用户界面。打开Qt Designer,创建一个新的窗口,添加以下组件:
- 一个
QListWidget
用于显示任务列表 - 一个
QLineEdit
用于输入新任务 - 两个
QPushButton
分别用于添加和删除任务
设计完成后,保存为mainwindow.ui
。
4.3 实现功能逻辑
接下来,我们在mainwindow.cpp
中实现功能逻辑。我们需要连接按钮的点击信号到相应的槽函数,以处理添加和删除任务的操作。
【代码】
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 连接信号和槽connect(ui->addButton, &QPushButton::clicked, this, &MainWindow::addTask);connect(ui->deleteButton, &QPushButton::clicked, this, &MainWindow::deleteTask);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::addTask()
{QString task = ui->taskInput->text();if (!task.isEmpty()) {ui->taskList->addItem(task);ui->taskInput->clear();}
}void MainWindow::deleteTask()
{QListWidgetItem *selectedItem = ui->taskList->currentItem();delete selectedItem;
}
【mermaid图】
【举例说明】
这个待办事项应用程序就像一个简单的日历。你可以在上面写下每天的任务(添加任务),也可以划掉已经完成的任务(删除任务)。通过Qt的信号与槽机制,我们实现了用户与应用之间的互动,提升了用户体验。
4.4 数据持久化
一个实用的待办事项应用程序需要能够保存用户的数据,这样用户关闭应用后再次打开时,之前的任务仍然存在。我们将使用Qt的设置系统来实现数据持久化。
【代码】
#include <QSettings>
#include <QStringList>class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void addTask();void deleteTask();void markTaskCompleted();private:Ui::MainWindow *ui;void loadTasks();void saveTasks();void setupTaskList();
};void MainWindow::loadTasks()
{QSettings settings("MyCompany", "TodoApp");QStringList tasks = settings.value("tasks").toStringList();QStringList completedTasks = settings.value("completedTasks").toStringList();for (const QString &task : tasks) {QListWidgetItem *item = new QListWidgetItem(task);if (completedTasks.contains(task)) {item->setCheckState(Qt::Checked);QFont font = item->font();font.setStrikeOut(true);item->setFont(font);} else {item->setCheckState(Qt::Unchecked);}ui->taskList->addItem(item);}
}void MainWindow::saveTasks()
{QSettings settings("MyCompany", "TodoApp");QStringList tasks;QStringList completedTasks;for (int i = 0; i < ui->taskList->count(); ++i) {QListWidgetItem *item = ui->taskList->item(i);tasks << item->text();if (item->checkState() == Qt::Checked) {completedTasks << item->text();}}settings.setValue("tasks", tasks);settings.setValue("completedTasks", completedTasks);
}void MainWindow::markTaskCompleted()
{QListWidgetItem *currentItem = ui->taskList->currentItem();if (currentItem) {QFont font = currentItem->font();if (currentItem->checkState() == Qt::Checked) {font.setStrikeOut(true);currentItem->setForeground(QColor(128, 128, 128));} else {font.setStrikeOut(false);currentItem->setForeground(QColor(0, 0, 0));}currentItem->setFont(font);saveTasks(); // 自动保存}
}
【mermaid图】
【举例说明】
数据持久化就像给你的笔记本加上了"云同步"功能。无论你什么时候打开笔记本,之前记录的内容都还在那里。QSettings就像是Qt提供的一个智能文件柜,它知道在不同操作系统上应该把数据存放在哪里(Windows的注册表、macOS的plist文件、Linux的配置文件等)。
4.5 美化界面
一个好看的界面能够显著提升用户体验。Qt提供了强大的样式表(QSS)功能,类似于网页开发中的CSS,让我们可以轻松美化应用程序。
【代码】
void MainWindow::setupUI()
{// 设置窗口样式this->setStyleSheet(R"(QMainWindow {background: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #f0f0f0, stop:1 #e0e0e0);}QListWidget {background-color: white;border: 2px solid #cccccc;border-radius: 8px;padding: 5px;font-size: 14px;}QListWidget::item {padding: 8px;border-bottom: 1px solid #eeeeee;}QListWidget::item:selected {background-color: #3498db;color: white;}QLineEdit {border: 2px solid #bdc3c7;border-radius: 6px;padding: 8px;font-size: 14px;}QLineEdit:focus {border-color: #3498db;}QPushButton {background-color: #3498db;color: white;border: none;border-radius: 6px;padding: 10px 20px;font-size: 14px;font-weight: bold;}QPushButton:hover {background-color: #2980b9;}QPushButton:pressed {background-color: #21618c;}QPushButton#deleteButton {background-color: #e74c3c;}QPushButton#deleteButton:hover {background-color: #c0392b;})");// 设置窗口图标和标题setWindowTitle("我的待办事项");setWindowIcon(QIcon(":/icons/todo.png"));// 设置最小窗口大小setMinimumSize(400, 500);
}
4.6 添加动画效果
现代应用程序离不开流畅的动画效果。Qt提供了强大的动画框架,让我们可以轻松添加各种动画效果。
【代码】
#include <QPropertyAnimation>
#include <QGraphicsOpacityEffect>
#include <QParallelAnimationGroup>class AnimatedListWidget : public QListWidget
{Q_OBJECTpublic:AnimatedListWidget(QWidget *parent = nullptr) : QListWidget(parent) {}void addItemWithAnimation(const QString &text) {QListWidgetItem *item = new QListWidgetItem(text);addItem(item);// 创建透明度效果QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect;effect->setOpacity(0.0);QWidget *itemWidget = new QWidget;itemWidget->setGraphicsEffect(effect);setItemWidget(item, itemWidget);// 创建淡入动画QPropertyAnimation *fadeIn = new QPropertyAnimation(effect, "opacity");fadeIn->setDuration(500);fadeIn->setStartValue(0.0);fadeIn->setEndValue(1.0);fadeIn->setEasingCurve(QEasingCurve::InOutQuad);fadeIn->start(QAbstractAnimation::DeleteWhenStopped);}void removeItemWithAnimation(QListWidgetItem *item) {if (!item) return;QWidget *itemWidget = this->itemWidget(item);if (!itemWidget) {delete item;return;}QGraphicsOpacityEffect *effect = qobject_cast<QGraphicsOpacityEffect*>(itemWidget->graphicsEffect());if (effect) {QPropertyAnimation *fadeOut = new QPropertyAnimation(effect, "opacity");fadeOut->setDuration(300);fadeOut->setStartValue(1.0);fadeOut->setEndValue(0.0);connect(fadeOut, &QPropertyAnimation::finished, [this, item]() {delete item;});fadeOut->start(QAbstractAnimation::DeleteWhenStopped);} else {delete item;}}
};
【mermaid图】
【举例说明】
添加动画效果就像给你的应用程序注入了生命力。想象一下,当你在手机上删除一条消息时,它不是突然消失,而是慢慢淡出,这种过渡效果让用户感觉更加自然和舒适。Qt的动画框架就像一个专业的动画师,能够帮你创造出各种流畅的视觉效果。
5. Qt Quick与QML
如果说Qt Widgets是传统的"命令式"编程方式,那么Qt Quick就是现代的"声明式"编程范式。QML(Qt Meta-Object Language)是一种声明式语言,专门用于创建流畅、现代化的用户界面。
想象一下,传统的Qt Widgets开发就像用代码一行一行地描述如何建造一座房子:"先放一块砖,再放一块砖,然后刷漆…"而QML则像是画一张房子的设计图:“我要一座蓝色屋顶的两层小楼,门在中间,窗户在两边…”
5.1 QML基础语法
QML的语法简洁优雅,即使是初学者也能快速上手。
【代码】
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15ApplicationWindow {id: windowwidth: 400height: 600visible: truetitle: "QML待办事项"property alias taskModel: taskModel// 数据模型ListModel {id: taskModelListElement { text: "学习Qt"; completed: false }ListElement { text: "写代码"; completed: true }ListElement { text: "喝咖啡"; completed: false }}ColumnLayout {anchors.fill: parentanchors.margins: 20// 输入区域RowLayout {Layout.fillWidth: trueTextField {id: taskInputLayout.fillWidth: trueplaceholderText: "输入新任务..."Keys.onReturnPressed: addTask()}Button {text: "添加"onClicked: addTask()}}// 任务列表ListView {id: taskListLayout.fillWidth: trueLayout.fillHeight: truemodel: taskModeldelegate: TaskItem {width: taskList.widthtaskText: model.textisCompleted: model.completedonToggleCompleted: {taskModel.setProperty(index, "completed", !model.completed)}onDeleteTask: {taskModel.remove(index)}}}}function addTask() {if (taskInput.text.trim() !== "") {taskModel.append({"text": taskInput.text,"completed": false})taskInput.text = ""}}
}
// TaskItem.qml - 自定义任务项组件
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15Rectangle {id: rootheight: 60color: mouseArea.containsMouse ? "#f5f5f5" : "white"border.color: "#e0e0e0"border.width: 1radius: 8property string taskText: ""property bool isCompleted: falsesignal toggleCompleted()signal deleteTask()// 动画效果Behavior on color {ColorAnimation { duration: 200 }}RowLayout {anchors.fill: parentanchors.margins: 10// 复选框CheckBox {id: checkboxchecked: root.isCompletedonToggled: root.toggleCompleted()}// 任务文本Text {Layout.fillWidth: truetext: root.taskTextfont.pixelSize: 16font.strikeout: root.isCompletedcolor: root.isCompleted ? "#888888" : "#333333"Behavior on color {ColorAnimation { duration: 200 }}}// 删除按钮Button {text: "删除"flat: trueonClicked: {// 添加删除动画deleteAnimation.start()}}}// 鼠标悬停效果MouseArea {id: mouseAreaanchors.fill: parenthoverEnabled: trueacceptedButtons: Qt.NoButton}// 删除动画ParallelAnimation {id: deleteAnimationNumberAnimation {target: rootproperty: "opacity"to: 0duration: 300}NumberAnimation {target: rootproperty: "height"to: 0duration: 300}onFinished: root.deleteTask()}
}
【mermaid图】
【举例说明】
QML就像是搭积木块,简单而直观。你只需描述你想要的界面,QML会自动处理所有的细节。想象一下,你在构建一个房子时,只需告诉它你想要的房间、窗户和门,而不必担心如何把每一块砖放到位。QML的声明式语法让开发者能够专注于设计和用户体验,而不是繁琐的实现细节。
5.2 QML与JavaScript结合
QML不仅支持声明式编程,还可以与JavaScript无缝结合,增强应用的交互性和逻辑处理能力。
【代码】
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15ApplicationWindow {id: windowwidth: 400height: 600visible: truetitle: "QML待办事项"property alias taskModel: taskModelListModel {id: taskModelListElement { text: "学习Qt"; completed: false }ListElement { text: "写代码"; completed: true }ListElement { text: "喝咖啡"; completed: false }}ColumnLayout {anchors.fill: parentanchors.margins: 20RowLayout {Layout.fillWidth: trueTextField {id: taskInputLayout.fillWidth: trueplaceholderText: "输入新任务..."Keys.onReturnPressed: addTask()}Button {text: "添加"onClicked: addTask()}}ListView {id: taskListLayout.fillWidth: trueLayout.fillHeight: truemodel: taskModeldelegate: TaskItem {width: taskList.widthtaskText: model.textisCompleted: model.completedonToggleCompleted: {taskModel.setProperty(index, "completed", !model.completed)}onDeleteTask: {taskModel.remove(index)}}}}function addTask() {if (taskInput.text.trim() !== "") {taskModel.append({"text": taskInput.text,"completed": false})taskInput.text = ""}}function clearCompletedTasks() {for (var i = taskModel.count - 1; i >= 0; i--) {if (taskModel.get(i).completed) {taskModel.remove(i);}}}
}
【mermaid图】
【举例说明】
结合JavaScript的QML就像给你的应用程序添加了一个智能助手。你可以轻松地处理复杂的逻辑,比如清理已完成的任务,而不必在每个操作中重复代码。通过这种方式,QML和JavaScript的结合使得开发变得更加灵活和高效。
5.3 QML的动态特性
QML的动态特性使得应用程序能够根据用户的输入和状态实时更新界面。
【代码】
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15ApplicationWindow {id: windowwidth: 400height: 600visible: truetitle: "QML待办事项"property alias taskModel: taskModelListModel {id: taskModelListElement { text: "学习Qt"; completed: false }ListElement { text: "写代码"; completed: true }ListElement { text: "喝咖啡"; completed: false }}ColumnLayout {anchors.fill: parentanchors.margins: 20RowLayout {Layout.fillWidth: trueTextField {id: taskInputLayout.fillWidth: trueplaceholderText: "输入新任务..."Keys.onReturnPressed: addTask()}Button {text: "添加"onClicked: addTask()}Button {text: "清除已完成"onClicked: clearCompletedTasks()}}ListView {id: taskListLayout.fillWidth: trueLayout.fillHeight: truemodel: taskModeldelegate: TaskItem {width: taskList.widthtaskText: model.textisCompleted: model.completedonToggleCompleted: {taskModel.setProperty(index, "completed", !model.completed)}onDeleteTask: {taskModel.remove(index)}}}}function addTask() {if (taskInput.text.trim() !== "") {taskModel.append({"text": taskInput.text,"completed": false})taskInput.text = ""}}function clearCompletedTasks() {for (var i = taskModel.count - 1; i >= 0; i--) {if (taskModel.get(i).completed) {taskModel.remove(i);}}}
}
【mermaid图】
【举例说明】
动态特性让你的应用程序能够实时响应用户的操作。想象一下,当你添加一个新任务时,列表会立即更新,用户无需手动刷新。这种即时反馈提升了用户体验,使得应用程序更加生动和互动。
结语
感谢您的阅读!期待您的一键三连!欢迎指正!