文章目录
正文
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图】
timeline
title Qt发展历程
1991 : Trolltech成立
1995 : Qt 0.90发布
1998 : KDE采用Qt
2005 : Qt 4.0发布
: 引入Graphics View
2009 : Qt 4.6发布
: 支持触摸和手势
2011 : Qt 5.0发布
: QML和Qt Quick
2020 : 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_OBJECT
private:
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(MyQtApp
main.cpp
mainwindow.cpp
mainwindow.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_OBJECT
public:
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_OBJECT
public:
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.15
ApplicationWindow {
id: window
width: 400
height: 600
visible: true
title: "QML待办事项"
property alias taskModel: taskModel
// 数据模型
ListModel {
id: taskModel
ListElement { text: "学习Qt"; completed: false }
ListElement { text: "写代码"; completed: true }
ListElement { text: "喝咖啡"; completed: false }
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
// 输入区域
RowLayout {
Layout.fillWidth: true
TextField {
id: taskInput
Layout.fillWidth: true
placeholderText: "输入新任务..."
Keys.onReturnPressed: addTask()
}
Button {
text: "添加"
onClicked: addTask()
}
}
// 任务列表
ListView {
id: taskList
Layout.fillWidth: true
Layout.fillHeight: true
model: taskModel
delegate: TaskItem {
width: taskList.width
taskText: model.text
isCompleted: model.completed
onToggleCompleted: {
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.15
Rectangle {
id: root
height: 60
color: mouseArea.containsMouse ? "#f5f5f5" : "white"
border.color: "#e0e0e0"
border.width: 1
radius: 8
property string taskText: ""
property bool isCompleted: false
signal toggleCompleted()
signal deleteTask()
// 动画效果
Behavior on color {
ColorAnimation { duration: 200 }
}
RowLayout {
anchors.fill: parent
anchors.margins: 10
// 复选框
CheckBox {
id: checkbox
checked: root.isCompleted
onToggled: root.toggleCompleted()
}
// 任务文本
Text {
Layout.fillWidth: true
text: root.taskText
font.pixelSize: 16
font.strikeout: root.isCompleted
color: root.isCompleted ? "#888888" : "#333333"
Behavior on color {
ColorAnimation { duration: 200 }
}
}
// 删除按钮
Button {
text: "删除"
flat: true
onClicked: {
// 添加删除动画
deleteAnimation.start()
}
}
}
// 鼠标悬停效果
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
}
// 删除动画
ParallelAnimation {
id: deleteAnimation
NumberAnimation {
target: root
property: "opacity"
to: 0
duration: 300
}
NumberAnimation {
target: root
property: "height"
to: 0
duration: 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.15
ApplicationWindow {
id: window
width: 400
height: 600
visible: true
title: "QML待办事项"
property alias taskModel: taskModel
ListModel {
id: taskModel
ListElement { text: "学习Qt"; completed: false }
ListElement { text: "写代码"; completed: true }
ListElement { text: "喝咖啡"; completed: false }
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
RowLayout {
Layout.fillWidth: true
TextField {
id: taskInput
Layout.fillWidth: true
placeholderText: "输入新任务..."
Keys.onReturnPressed: addTask()
}
Button {
text: "添加"
onClicked: addTask()
}
}
ListView {
id: taskList
Layout.fillWidth: true
Layout.fillHeight: true
model: taskModel
delegate: TaskItem {
width: taskList.width
taskText: model.text
isCompleted: model.completed
onToggleCompleted: {
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.15
ApplicationWindow {
id: window
width: 400
height: 600
visible: true
title: "QML待办事项"
property alias taskModel: taskModel
ListModel {
id: taskModel
ListElement { text: "学习Qt"; completed: false }
ListElement { text: "写代码"; completed: true }
ListElement { text: "喝咖啡"; completed: false }
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
RowLayout {
Layout.fillWidth: true
TextField {
id: taskInput
Layout.fillWidth: true
placeholderText: "输入新任务..."
Keys.onReturnPressed: addTask()
}
Button {
text: "添加"
onClicked: addTask()
}
Button {
text: "清除已完成"
onClicked: clearCompletedTasks()
}
}
ListView {
id: taskList
Layout.fillWidth: true
Layout.fillHeight: true
model: taskModel
delegate: TaskItem {
width: taskList.width
taskText: model.text
isCompleted: model.completed
onToggleCompleted: {
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图】
【举例说明】
动态特性让你的应用程序能够实时响应用户的操作。想象一下,当你添加一个新任务时,列表会立即更新,用户无需手动刷新。这种即时反馈提升了用户体验,使得应用程序更加生动和互动。
结语
感谢您的阅读!期待您的一键三连!欢迎指正!