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

学习 nana c++ 库 (一)

介绍

Nana C++ Library —— 最现代、最符合现代 C++ 风格的框架

如果你想学习现代 C++(C++11/14/17 及以上)的标准语法,Nana 是几乎完美的方案。很多传统的 GUI 框架(如 MFC)因为历史原因,充斥着大量的宏和自定义类型,而 Nana 完全是用现代 C++ 重新设计的。

为什么适合新手:

标准 C++ 风格:它大量使用了标准库(std::string、std::function、智能指针等)。学 Nana 的过程,就是在复习标准 C++。

极其优雅的事件处理:它没有晦涩的宏,而是使用 C++11 的 Lambda 表达式来处理点击事件:

        btn.events().click([](){ std::cout << "Button clicked!" << std::endl; });

轻量跨平台:只需包含头文件和源文件即可,没有复杂的配置。

学习资源

Nana 官方原先的域名 nanapro.org 确实由于疏于维护失效了。不过不用担心,开源社区以及作者在 GitHub 上留下了非常完整的复刻版(Mirror)和文档托管地址。

你可以使用以下这几个依然活跃、且内容完全对齐的替代地址:

1. 官方最全的 API 参考手册(Doxygen 复刻版)

这是目前最完整、最好用的 Nana 在线类库参考文档,由社区核心贡献者维护,详细列出了每个控件、API 的定义及 Demo:
👉 qPCR4vir 的 Nana Doxygen 托管页

怎么用:点击左侧的 ClassesNamespaces 即可查询具体的控件(如 nana::buttonnana::form)的使用方法。

2. 官方中文/英文使用指南(Nana Handbook)

如果你需要看通俗易懂的入门教程(讲解事件处理、布局管理等基础概念),官方有一个专门的 Handbook 仓库。你可以直接在 GitHub 上流畅阅读:
👉 GitHub - cnjinhao/nana-handbook (在线阅读手册)

3. 官方历史网页备份(Wayback Machine)

如果你依然想看当年官方网站(En-US 英文版)原汁原味的排版、博客和答疑:
👉 Wayback Machine 上的 nanapro.org 历史快照备份


💡 额外的小建议

看 Nana 的文档时,建议搭配它的源码示例一起看。Nana 的主要作者其实是中国开发者(Jinhao),源码和官方 Handbook 的代码逻辑非常清晰。

你可以直接克隆它的主仓库,里面的 examples/ 文件夹包含了各种基础控件、多线程 UI、复杂布局(nana::place)的直观写法,比干看文档要高效得多!

hello world 小程序

无字版

#include <nana/gui.hpp>int main()
{nana::form fm;fm.show();nana::exec();
}

hello world 版

#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>int main()
{// 创建窗体nana::form fm{nana::API::make_center(400, 200)};fm.caption("Nana Hello World");// 创建标签nana::label lbl{ fm, nana::rectangle{100, 70, 200, 30} };lbl.caption("Hello World");// 可选:居中显示文字lbl.text_align(nana::align::center);fm.show();nana::exec();
}

nana 复杂版 hello world

#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/place.hpp>int main()
{nana::form fm{nana::API::make_center(400, 200)};fm.caption("Nana Hello World");nana::label lbl{ fm };lbl.caption("Hello World");lbl.text_align(nana::align::center);nana::place plc{ fm };plc.div("margin=20 <text>");plc["text"] << lbl;plc.collocate();fm.show();nana::exec();
}

用virual studio 2026 编译运行

  1. 下载 nana 库 https://github.com/cnjinhao/nana/archive/refs/tags/v1.7-alpha.zip,解压并更改目录名为 nana,
  2. 同时建立目录 MyNanaApp,新建两个文件 main.cpp CMakeLists.txt,完整的目录系统如下:
├── nana/               (你下载的 Nana 源码文件夹)
└── MyNanaApp/          (你自己的项目文件夹)├── main.cpp        (写入你上面那段代码)└── CMakeLists.txt  (新建一个文本文件,命名为此名字)
  1. 编写CMakeLists.txt文件
cmake_minimum_required(VERSION 3.15)
project(MyNanaApp LANGUAGES CXX)# 设置 C++ 标准为现代 C++(Nana 推荐 C++17 或更高)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 自动寻找并包含隔壁的 Nana 源码
add_subdirectory(../nana ${CMAKE_CURRENT_BINARY_DIR}/nana_build)# 定义你的可执行程序
add_executable(MyNanaApp main.cpp)# 让你的程序链接到 nana 库(CMake 会自动处理头文件包含路径)
target_link_libraries(MyNanaApp PRIVATE nana)

但这个cmake 配置会出一个小问题:

  [21/22] Linking CXX static library nana_build\nana.lib
  [22/22] Linking CXX executable MyNanaApp.exe
  FAILED: [code=4294967295] MyNanaApp.exe 
  C:\Windows\system32\cmd.exe /C "cd . && "C:\Program Files\Microsoft Visual Studio\18\Insiders\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --msvc-ver=1951 --intdir=CMakeFiles\MyNanaApp.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100280~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100280~1.0\x64\mt.exe --manifests  -- C:\PROGRA~1\MICROS~1\18\Insiders\VC\Tools\MSVC\1451~1.362\bin\Hostx64\x64\link.exe /nologo CMakeFiles\MyNanaApp.dir\main.cpp.obj  /out:MyNanaApp.exe /implib:MyNanaApp.lib /pdb:MyNanaApp.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console  nana_build\nana.lib  stdc++fs.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
  LINK Pass 1: command "C:\PROGRA~1\MICROS~1\18\Insiders\VC\Tools\MSVC\1451~1.362\bin\Hostx64\x64\link.exe /nologo CMakeFiles\MyNanaApp.dir\main.cpp.obj /out:MyNanaApp.exe /implib:MyNanaApp.lib /pdb:MyNanaApp.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console nana_build\nana.lib stdc++fs.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\MyNanaApp.dir/intermediate.manifest CMakeFiles\MyNanaApp.dir/manifest.res" failed (exit code 1104) with the following output:
C:\Users\Logic\source\repos\MyNanaApp\out\build\x64-Debug\LINK : fatal error LNK1104: 无法打开文件“stdc++fs.lib”
  
  ninja: build stopped: subcommand failed.

解决方法是修改 CMakeLists.txt 文件

编译出了 nana.lib,但在最后一步链接成 MyNanaApp.exe 时卡住了。

为什么会报 LNK1104: 无法打开文件“stdc++fs.lib”

在旧版本的 C++(如早期的 C++17)中,文件系统库 std::filesystem 还在实验阶段,需要额外链接 stdc++fs.lib。但随着现代编译器(尤其是你的 VS2026/MSVC)的发展,std::filesystem 已经直接集成在标准 C++ 核心库中了。

错误的原因是:Nana 库自带的 CMake 脚本比较旧,它固执地认为 C++17 环境下“必须强制去链接 stdc++fs.lib”,然而新版 VS2026 里面已经彻底删除了这个独立的 .lib 文件,所以链接器找不到它,报错了。


💡 解决方案:在你的 CMakeLists.txt 中干掉这个死板的依赖

既然编译器已经内置了文件系统,我们只需要在你的 CMakeLists.txt 里加一个小魔法,把 Nana 错误引入的 stdc++fs 库“偷梁换柱”成一个空目标即可。

请把你的 CMakeLists.txt 修改为如下内容(看第 9 行起的 if(MSVC) 部分):

cmake_minimum_required(VERSION 3.15)
project(MyNanaApp LANGUAGES CXX)# 使用 C++17 
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)if(MSVC)add_compile_options(/Zc:__cplusplus)# 【核心修复】欺骗 CMake,创建一个假的、空的 stdc++fs 目标# 这样当 Nana 试图去链接 stdc++fs 时,实际上什么都不会做,直接使用 VS 内置的文件系统if(NOT TARGET stdc++fs)add_library(stdc++fs INTERFACE)endif()
endif()# 自动寻找并包含隔壁的 Nana 源码
add_subdirectory(../nana ${CMAKE_CURRENT_BINARY_DIR}/nana_build)# 定义你的可执行程序
add_executable(MyNanaApp main.cpp)# 让你的程序链接到 nana 库
target_link_libraries(MyNanaApp PRIVATE nana)

🛠️ 若 CMakeLists文件没有更新,要手动刷新:

修改完并保存 CMakeLists.txt 后,请务必刷新 CMake 缓存:

  1. 在 VS2026 顶部菜单栏点击:“项目” (Project) -> “删除缓存并重新配置” (Delete Cache and Reconfigure)
  2. 等待底部状态栏的 CMake 配置重新加载完毕。
  3. 按下 F5 重新编译运行。

这次链接器就不会再去寻找那个不存在的 stdc++fs.lib,你的绿色小窗口应该就能顺利弹出来了!

注意,nana 库只能用 c++ 17,不支持 C++ 20,否则也会报错。

严重性    代码    说明    项目    文件    行    抑制状态    详细信息
错误    C2440    “return”: 无法从“std::basic_string<char8_t,std::char_traits<char8_t>,std::allocator<char8_t>>”转换为“std::basic_string<char,std::char_traits<char>,std::allocator<char>>”    C:\Users\Logic\source\repos\MyNanaApp\out\build\x64-Debug\MyNanaApp    C:\Users\Logic\source\repos\nana\include\nana\filesystem\filesystem_ext.hpp    44        

这个错误是典型的 C++20 新特性导致的兼容性冲突

为什么会报错?

在 C++20 标准中,引入了全新的 UTF-8 字符类型 char8_t。这导致原本在 C++17 中会返回普通字符串(std::string,即 char 类型)的某些文件系统函数(如 std::filesystem::path::string()),在 C++20 下被强制返回 std::u8string(即 char8_t 类型)。

Nana 库的底层代码在编写时,可能还没有完全兼容 C++20 的这一霸道改动,导致了代码在第 44 行试图直接把 char8_t 的字符串当成普通 char 字符串返回,从而引发了 C2440: 无法转换 的错误。


💡 解决方案

解决这个问题有两个方向:方案一(最省心,强烈推荐) 是微调编译选项,让编译器在 C++20 下对 char8_t 进行向下兼容;方案二 是退回 C++17。

方案一:在 CMake 中关闭 C++20 的 char8_t 严格模式(推荐)

微软的 MSVC 编译器提供了一个极其贴心的开关:/Zc:char8_t-(注意后面有个减号),它可以让编译器在 C++20 环境下,依然把 UTF-8 字符串当做普通的 char 字符串处理。这样既能享受 C++20 的其他新特性,又能完美兼容 Nana 库。

请把你的 CMakeLists.txt 修改为如下内容(重点看 if(MSVC) 内部的变化):

cmake_minimum_required(VERSION 3.15)
project(MyNanaApp LANGUAGES CXX)# 将 C++ 标准提升至 C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 针对 VS/MSVC 编译器的 C++20 优化
if(MSVC)add_compile_options(/Zc:__cplusplus)add_compile_options(/Zc:preprocessor)# 【核心修复】关闭 C++20 的 char8_t 严格类型,允许其隐式转换为普通 stringadd_compile_options(/Zc:char8_t-)
endif()# 自动寻找并包含隔壁的 Nana 源码
add_subdirectory(../nana ${CMAKE_CURRENT_BINARY_DIR}/nana_build)# 定义你的可执行程序
add_executable(MyNanaApp main.cpp)# 让你的程序链接到 nana 库
target_link_libraries(MyNanaApp PRIVATE nana)

修改后非常重要的一步
保存 CMakeLists.txt 后,在 VS2026 顶部菜单栏点击:“项目” (Project) -> “删除缓存并重新配置” (Delete Cache and Reconfigure)。然后再重新点击运行(F5),这个报错就会彻底消失!


方案二:降回 C++17

如果你觉得上面的黑魔法不够稳妥,或者之后还会遇到类似的 C++20 兼容问题,最稳健的做法是直接在 CMakeLists.txt 里把标准改回 C++17:

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

因为 C++17 没有 char8_t 严格类型的限制,Nana 源码在此标准下可以毫无阻碍地编译通过。对于初学者进阶来说,C++17 的特性也已经完全够用了。

http://www.jsqmd.com/news/1036064/

相关文章:

  • Python开发工具指南:提升你的开发效率
  • 快速制作投票活动链接的最新教程,必备干货!
  • TLM2.0
  • 2026多品牌大电流微欧计实测:青岛普锐思高口碑生产商测评 - 品牌推荐大师
  • 2026武汉真人发假发定制推荐:武汉三星速美假发超市实力全盘点 - 行业深度观察C
  • 基于MC68HC908MR32的永磁同步电机正弦波驱动与死区补偿技术详解
  • NXP T4240RDB参考设计板硬件架构解析与设计实践
  • 百度网盘秒传解决方案:高效文件管理与分享终极指南
  • 外贸快车怎么样?实力测评解析 - 栗子测评
  • 如何三步快速解密Navicat数据库连接密码的完整免费解决方案
  • 终极跨平台Access数据库处理方案:MDB Tools实战指南
  • Motorola Suite56 ADS调试器:OnCE与MFAX技术深度解析与实战指南
  • 5分钟搞定Windows和Office激活:KMS智能脚本终极指南
  • 嵌入式功能安全实战:基于NXP IEC60730库的GPIO短路与Flash CRC校验
  • 2026年6月18日海安车灯维修本地走访记:裂痕位置、进水情况和灯壳状态先核对哪几项 - Ayu8888
  • B站视频解析技术深度解析:多协议支持与智能缓存实现
  • 杰理之USB SPK位宽设置24bit,插PC会死机【篇】
  • 嵌入式异构多核硬件设计实战:TWR-VF65GS10开发板深度解析
  • Mythos能力跃迁:系统级推理与具身叙事的工程落地
  • 3个必装理由:为什么你需要PowerToys中文版来提升Windows效率?
  • 3步掌握OpenSlide:从零开始高效处理虚拟切片图像
  • 2026拉力机试验机品牌推荐榜:技术派vs性价比派,你选哪一派? - 品牌推荐大师1
  • 2026年采购合同风险意识不足,咨询众智商学院CPPM前应该先看哪些条款和案例 - 众智商学院官方
  • 杭州思亿欧智能体科技有限公司靠谱么?公司综合实力深度解析 - 栗子测评
  • 考软考中项报培训班一般多少钱?哪家性价比高
  • Poppins字体终极指南:如何高效运用这款现代几何无衬线字体提升你的设计质感
  • 【2027最新】基于SpringBoot+Vue的汽车维修预约服务系统管理系统源码+MyBatis+MySQL
  • 计算机Java毕设实战-基于 Spring Boot 的二手房交易信息管理系统的设计与实现 基于 Spring Boot 的房屋买卖供需对接系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • zip slip目录遍历加n1例题
  • 哈尔滨本土门窗厂家排行:适配寒地需求的实力之选 - 起跑123