当前位置: 首页 > news >正文

Chromium GN 目标指南 - view_example 计数器示例 (七)

1. 引言

在前面的文章中,我们学习了如何在 views_examples 中添加自定义 Button 示例。在本篇文章中,我们将继续探索 Views 框架的应用,创建一个简单的计数器示例,以学习如何使用 Label 和 Button 控件进行交互,以及如何更新 UI 状态。

2. 创建计数器示例

为了创建计数器示例,我们需要创建新的头文件和源文件,并在其中定义计数器类和相关的示例代码。

2.1 创建头文件

首先,我们在 ui/views/examples/ 目录下创建一个名为 counter_example.h 的头文件,并在其中添加以下代码:

#ifndef UI_VIEWS_EXAMPLES_COUNTER_EXAMPLE_H_
#define UI_VIEWS_EXAMPLES_COUNTER_EXAMPLE_H_#include "ui/views/controls/button/button.h"
#include "ui/views/controls/label.h"
#include "ui/views/examples/example_base.h"namespace views::examples {class CounterExample : public ExampleBase {public:CounterExample();CounterExample(const CounterExample&) = delete;CounterExample& operator=(const CounterExample&) = delete;~CounterExample() override = default;// ExampleBase:void CreateExampleView(View* container) override;private:void UpdateCounter();void OnDecreaseClicked();void OnIncreaseClicked();void OnResetClicked();int counter_;raw_ptr<views::Label> counter_label_ = nullptr;raw_ptr<views::Label> status_label_ = nullptr;
};}  // namespace views::examples#endif  // UI_VIEWS_EXAMPLES_COUNTER_EXAMPLE_H_

这段代码定义了一个名为 CounterExample 的类,它继承自 ExampleBase。在 CounterExample 类中,我们声明了四个私有成员函数:UpdateCounterOnDecreaseClickedOnIncreaseClickedOnResetClicked,分别用于更新计数器、处理减少按钮点击事件、处理增加按钮点击事件和处理重置按钮点击事件。我们还声明了一个 int 类型的成员变量 counter_ 用于存储计数器的值,以及两个 raw_ptr<views::Label> 类型的成员变量 counter_label_status_label_,分别用于显示计数器的值和状态信息。

2.2 创建源文件

接下来,我们在 ui/views/examples/ 目录下创建一个名为 counter_example.cc 的源文件,并在其中添加以下代码:

#include "ui/views/examples/counter_example.h"#include "base/functional/bind.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/controls/label.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"namespace views::examples {CounterExample::CounterExample() : ExampleBase("Counter Example"), counter_(0) {}void CounterExample::CreateExampleView(View* container) {// 使用水平布局auto* layout = new views::BoxLayout(views::BoxLayout::Orientation::kHorizontal, gfx::Insets(10), // 边距20); // 组件间距container->SetLayoutManager(std::unique_ptr<views::BoxLayout>(layout));// 减少按钮auto* decrease_button = new views::MdTextButton(base::BindRepeating(&CounterExample::OnDecreaseClicked,base::Unretained(this)),u"-");decrease_button->SetStyle(ui::ButtonStyle::kText);container->AddChildView(decrease_button);// 计数显示标签counter_label_ = new views::Label(u"0");counter_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);counter_label_->SetSize(gfx::Size(50, 0)); // 设置标签大小container->AddChildView(counter_label_);// 增加按钮auto* increase_button = new views::MdTextButton(base::BindRepeating(&CounterExample::OnIncreaseClicked,base::Unretained(this)),u"+");increase_button->SetStyle(ui::ButtonStyle::kText);container->AddChildView(increase_button);// 重置按钮auto* reset_button = new views::MdTextButton(base::BindRepeating(&CounterExample::OnResetClicked,base::Unretained(this)),u"Reset");reset_button->SetStyle(ui::ButtonStyle::kTonal);container->AddChildView(reset_button);// 状态标签status_label_ = new views::Label(u"Counter initialized");container->AddChildView(status_label_);
}void CounterExample::UpdateCounter() {counter_label_->SetText(base::UTF8ToUTF16(std::to_string(counter_)));LOG(INFO) << "Counter value: " << counter_;
}void CounterExample::OnDecreaseClicked() {counter_--;UpdateCounter();status_label_->SetText(u"Counter decreased");
}void CounterExample::OnIncreaseClicked() {counter_++;UpdateCounter();status_label_->SetText(u"Counter increased");
}void CounterExample::OnResetClicked() {counter_ = 0;UpdateCounter();status_label_->SetText(u"Counter reset");
}}  // namespace views::examples 

这段代码实现了 CounterExample 类的构造函数和 CreateExampleViewUpdateCounterOnDecreaseClickedOnIncreaseClickedOnResetClicked 方法。

  • CounterExample::CounterExample(): 构造函数,调用了父类 ExampleBase 的构造函数,并设置了示例的名称为 "Counter Example",同时初始化 counter_ 为 0。
  • CounterExample::CreateExampleView(View* container): 这个方法负责创建并添加计数器相关的控件到 container 中。
    • 首先,它创建了一个水平布局管理器 BoxLayout,并将其设置给 container
    • 然后,它创建了四个按钮:
      • decrease_button: 减少按钮,点击后会调用 OnDecreaseClicked 方法。
      • increase_button: 增加按钮,点击后会调用 OnIncreaseClicked 方法。
      • reset_button: 重置按钮,点击后会调用 OnResetClicked 方法。
    • 接着创建了一个 Label 控件 counter_label_,用于显示计数器的值,设置其水平对齐方式为居中,并设置了最小宽度为50像素。
    • 最后创建了一个 Label 控件 status_label_,用于显示计数器的状态信息。
  • CounterExample::UpdateCounter(): 这个方法用于更新 counter_label_ 的文本内容,将其设置为当前计数器的值,并在日志中输出当前计数器的值。
  • CounterExample::OnDecreaseClicked(): 当 decrease_button 被点击时,这个方法会被调用。它会将计数器 counter_ 的值减1,调用 UpdateCounter 方法更新 counter_label_ 的显示,并将 status_label_ 的文本设置为 "Counter decreased"。
  • CounterExample::OnIncreaseClicked(): 当 increase_button 被点击时,这个方法会被调用。它会将计数器 counter_ 的值加1,调用 UpdateCounter 方法更新 counter_label_ 的显示,并将 status_label_ 的文本设置为 "Counter increased"。
  • CounterExample::OnResetClicked(): 当 reset_button 被点击时,这个方法会被调用。它会将计数器 counter_ 的值重置为0,调用 UpdateCounter 方法更新 counter_label_ 的显示,并将 status_label_ 的文本设置为 "Counter reset"。

3. 修改 BUILD.gn 文件

为了将我们的计数器示例添加到构建系统中,我们需要修改 ui/views/examples/BUILD.gn 文件,将我们新创建的源文件添加到 examples 目标的 sources 属性中。

打开 ui/views/examples/BUILD.gn 文件,找到 views_examples_lib 部分,并在 sources 列表中添加以下两行:

"counter_example.cc",
"counter_example.h",

4. 注册示例

最后,我们需要在 ui/views/examples/create_examples.cc 文件中注册我们的计数器示例,这样 views_examples 程序才能找到并显示它。

打开 ui/views/examples/create_examples.cc 文件,找到 CreateExamples 函数,并在 examples 向量中添加以下代码:

examples.push_back(std::make_unique<CounterExample>());

修改后的 CreateExamples 函数应该类似于这样:

ExampleVector CreateExamples() {ExampleVector examples;// ... 其他示例 ...examples.push_back(std::make_unique<MyCustomButtonExample>());examples.push_back(std::make_unique<CounterExample>());// ... 其他示例 ...return examples;
}

5. 重新编译并运行

完成以上步骤后,我们需要重新编译 views_examples 目标。在 Chromium 源码的 src 目录下执行以下命令:

autoninja -C out/Default views_examples

编译完成后,运行 views_examples

./out/Default/views_examples

如果一切顺利,你将在 "Views Examples" 窗口中看到一个新的标签页 "Counter Example",点击该标签页,你将看到我们自定义的计数器,包括一个显示计数器值的 Label,以及减少、增加和重置三个按钮。点击不同的按钮,计数器的值会相应地改变,同时下方的 Label 会显示相应的状态信息。

6. 结语

在本篇文章中,我们学习了如何在 views_examples 中添加计数器示例,包括创建头文件和源文件、修改 BUILD.gn 文件、注册示例以及重新编译和运行。通过这个过程,我们学习了如何使用 Label 和 Button 控件进行交互,以及如何更新 UI 状态。

希望这篇文章能够帮助你更好地理解 Chromium 的 Views 框架和 GN 构建系统。在接下来的文章中,我们将继续探索 Chromium 和 GN 的更多高级用法。

http://www.lryc.cn/news/509211.html

相关文章:

  • 一步一步写线程之十六线程的安全退出之二例程
  • 【Linux系列】Shell 脚本中的条件判断:`[ ]`与`[[ ]]`的比较
  • ArcGIS+MIKE21 洪水淹没分析、溃坝分析,洪水淹没动态效果
  • Git 的基本概念和使用
  • *【每日一题 基础题】 [蓝桥杯 2024 省 B] 好数
  • 对中文汉字排序的方法总结
  • 【解决报错】AttributeError: ‘NoneType‘ object has no attribute ‘group‘
  • 数据结构经典算法总复习(上卷)
  • JS获取URL中参数值的4种方法
  • 【面经】2024年软件测试面试题,精选100 道(附答案)
  • LabVIEW水泵性能测试系统
  • React 第十九节 useLayoutEffect 用途使用技巧注意事项详解
  • 重温设计模式--2、设计模式七大原则
  • 【NLP高频面题 - Transformer篇】Transformer的位置编码是如何计算的?
  • 基于SSM(Spring + Spring MVC + MyBatis)框架构建一个图书馆仓储管理系统
  • web的五个Observer API
  • Java基础:抽象类与接口
  • llama.cpp:PC端测试 MobileVLM -- 电脑端部署图生文大模型
  • Web前端基础知识(一)
  • 基于谱聚类的多模态多目标浣熊优化算法(MMOCOA-SC)求解ZDT1-ZDT4,ZDT6和工程应用--盘式制动器优化,MATLAB代码
  • 国标GB28181摄像机接入EasyGBS如何通过流媒体技术提升安防监控效率?
  • [Unity] ShaderGraph动态修改Keyword Enum,实现不同效果一键切换
  • Unity开发哪里下载安卓Android-NDK-r21d,外加Android Studio打包实验
  • FFTW基本概念与安装使用
  • 【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
  • 教师如何打造专属私密成绩查询系统?
  • 【1224】C选填(字符串\0占大小,类大小函数调用,const定义常量,逗号表达式取尾,abs返回值
  • 本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——终篇
  • 复合机器人:开启智能制造新时代
  • 装饰者模式