Nana C++ Library:2012年新年快乐

Jinhao 2012-02-01 02:19:09
尽管C++是一门强大且语法灵活的语言,实际上,许多程序员并不喜欢用C++开发GUI,这是因为用C++来开发GUI太过复杂。现存的一些C++ GUI框架定义了一些规则,它需要你写出一些死板的代码才能运行,这总会导致一些问题,例如,让你在深度的继承层次中纠结,难以维护。现在,有另一个选择了,Nana C++ Library,一个纯粹的C++库,让你能完全发挥你的C++知识/技巧/手法来编写GUI,这是用C++开发GUI的一个重大的进步。

易学,易用

用Nana创建一个Hello World程序有多易?

#include <nana/gui/wvl.hpp>
#include <nana/gui/widgets/label.hpp>
int main()
{
using namespace nana::gui;
form fm;
label lb(fm, 0, 0, fm.size().width, fm.size().width);
lb.caption(STR("Hello, World"));
fm.show();
exec();
}


非常简单,易懂的代码。Nana引入简单和合理的概念使其保持简洁。其次,不像那些由于命名约束和语法约束导致编写死板代码的框架,Nana能使你的代码更加直观和可读。例如,响应一个事件:

#include <nana/gui/wvl.hpp>
#include <nana/gui/widgets/button.hpp>

void clicked(const nana::gui::eventinfo&)
{
//当点击窗口,该函数则被调用。
}

int main()
{
using namespace nana::gui;
form fm;
fm.make_event<events::click>(clicked);
fm.show();
exec();
}

函数clicked()的名字并不是强约束的,你可以给它任意取一个名字。这比通过继承某个事件接口来实现响应的方法更加直观。在某些情况下,我们并不需要关心clicked()函数的的参数,例如上面那个示例。

void clicked() //无参数.
{
//当点击窗口,该函数则被调用。
}

fm.make_event<events::click>(clicked); //Nana同样允许!

非常灵活,使你的代码保持简单明了。这个特性同样适用于函数对象。

什么使Nana如此灵活?

Nana C++ Library 不包含任何“额外的编译器”来解析“特殊的语法”, Nana使用100%的C++和模板技术使其强大和灵活。Nana并非像其他那些基于模板的程序库, 导致大量的代码膨胀,并且要求程序员具有模板技巧。Nana对 C++的新手来说也是非常友好的。

Nana是一个完完全全的C++风格的程序库,能运行在Visual C++ 7.1/GCC 3.4及以上的编译器。如果你是C++专家,Nana也允许你使用C++11中最新的特性Lambda来处理事件。例如

fm.make_event<events::click>([]{
//当窗口被点击, 这个由lambda创建的对象会被“调用”
});

or

fm.make_event<events::click>([](const eventinfo& ei){
//当窗口被点击, 这个由lambda创建的对象会被调用,
//并且通过ei可以获取这个事件的参数信息
});

另外,如果Nana与C++11中的std::bind一起使用,就能获得更大的灵活性。

多线程

简单地说,Nana是线程安全的,在不同的线程中访问widget对象也变成平常的事情。这是一个重要的特性,可以让程序员很方便的把事件处理提交由其他的线程处理。例如

#include <nana/gui/wvl.hpp>
#include <nana/threads/pool.hpp>

void foo()
{
//该函数会在由线程池创建的线程中“调用”
}

int main()
{
using namespace nana::gui;
using namespace nana::threads;

pool thrpool;
form fm;
fm.make_event<events::click>(pool_push(thrpool, foo));
fm.make_event<events::click>(pool_push(thrpool, []{
//同样可以使用Lambda表达式
}));
fm.show();
exec();
}


RAII

有一个重要的特性,展现在上面那些示例中。当form对象被创建,与它对应的窗口也会被创建,而这个窗口会一直隐藏着,直到调用了show()方法。当form对象被销毁,与它对应的窗口也随之关闭,这也符合C++的对象生命周期的概念。

跨平台编程

Nana C++ Library 是被设计成用来进行跨平台编程的,虽然第一个版本的发布只能运行在Windows上,但是现在这个库基本上移植到Linux(X11)平台上了。

最重要的特性:免费

这是一个开源的项目,对于非商业应用和商业应用来说都是免费的。

========
项目网址
当前版本:0.1.17(Alpha)
适用对象:C++程序员,且想为自己兴趣项目寻找方便轻巧的C++ GUI界面库。

欢迎各种意见和建议!共同探讨!
...全文
7233 130 打赏 收藏 转发到动态 举报
写回复
用AI写文章
130 条回复
切换为时间正序
请发表友善的回复…
发表回复
ssa 2014-01-23
  • 打赏
  • 举报
回复
请问一下tray如何用
卡卡Gemini 2012-09-28
  • 打赏
  • 举报
回复
好多大牛啊,我一直觉得MFC的数据和界面糅合在一起很恶心,只能想到个简单的办法,就是虚继承CDialog,然后用bridge模式在后台做一个数据处理的类,然后把数据和界面分离开来。至于像LZ这么做,暂时没想出好的办法。有空在好好研究LZ的源码。目前觉得涉及图形界面的,还是C#最好用。
zhiqiang21 2012-09-27
  • 打赏
  • 举报
回复
看到好多的大牛啊,学习了
fwlyd 2012-09-26
  • 打赏
  • 举报
回复
学习 。努力。
Daetalus 2012-09-26
  • 打赏
  • 举报
回复
支持,有兴趣参与!
Only_One_Only 2012-02-19
  • 打赏
  • 举报
回复
虽然还没有使用,先顶下。
永磁体呵呵哒 2012-02-18
  • 打赏
  • 举报
回复
支持一下。
abc_362425 2012-02-14
  • 打赏
  • 举报
回复
楼主很强大
lanzhengpeng2 2012-02-13
  • 打赏
  • 举报
回复
graphics是一个纯粹的抽象类,然后再通过实现graphics的派生来来完成绘制,而不是将绘制代码放在graphics里.这样,哪怕在Windows里,也可以有自定义的实现,如我就需要自定义一个基于DX的graphics.
struct WindowsGDIGraphics : graphics{};
struct Direct3DGraphics : graphics{};

[Quote=引用 135 楼 jinhao 的回复:]

>>map的查找可能很快了.但那个copy函数的存在让我很不爽.
指的哪个copy? 是那个将事件句柄从table拷贝到一个queue中? 从现在的设计上来说,这是必须的,也是正确的。

>>能将graphics抽象出来是最好的
现在的实现就是这样的,界面的绘制与平台无关,它仅依赖graphics。
[/Quote]
唐门问心 2012-02-13
  • 打赏
  • 举报
回复
继续认真研究一下……
火丁 2012-02-13
  • 打赏
  • 举报
回复
虽然还没有使用,但是真的感觉很不错,难得
Jinhao 2012-02-13
  • 打赏
  • 举报
回复
[Quote=引用 138 楼 lanzhengpeng2 的回复:]

graphics是一个纯粹的抽象类,然后再通过实现graphics的派生来来完成绘制,而不是将绘制代码放在graphics里.这样,哪怕在Windows里,也可以有自定义的实现,如我就需要自定义一个基于DX的graphics.
struct WindowsGDIGraphics : graphics{};
struct Direct3DGraphics : graphics{};
[/Quote]

现在的实现是揉在一起。因为我发现这个东西可以动态可配的话,会有一个复杂的问题。因为在配置上可能D3D和GDI有很大的不同,而配置这部分又并非与graphics相关联的,还有窗口部分。例如在Linux,在有了完备的X11的实现,也不可能简单地将X11转换成framebuffer,framebuffer下没有窗口的概念。
其实这些问题都是需要解决的,但是有些相关的又不够明确,所以现在是暂时搁置。在做抽象的时候,并不是只根据具体事物的特征进行抽象,还需要考虑各种的环境。现在graphics的一些成员函数也是在考虑Windows和Xlib上的差异才设计出来的。
如果这个库能完成对D3D/OpenGL的实现,那最后会以不同的版本形式存在,而不是在一个包含很全的版本中以自定义配置的形式存在,因为这样库上的设计就太复杂了,而且在使用的时候,配置的方法可能也不会很简单。
cadinfo 2012-02-11
  • 打赏
  • 举报
回复
支持楼主,不过现阶段宁可用QT,QT跨平台,且支持手机,如日中天啊
Jinhao 2012-02-10
  • 打赏
  • 举报
回复
>>map的查找可能很快了.但那个copy函数的存在让我很不爽.
指的哪个copy? 是那个将事件句柄从table拷贝到一个queue中? 从现在的设计上来说,这是必须的,也是正确的。

>>能将graphics抽象出来是最好的
现在的实现就是这样的,界面的绘制与平台无关,它仅依赖graphics。
lanzhengpeng2 2012-02-10
  • 打赏
  • 举报
回复
我对MFC是非常熟悉的.接触使用MFC已经有13年历史了.同时,我对dotNet的UI也了解一些,并在dotNet下,写了一套用于游戏的GUI.
现在无论是MFC也好,还是dotNet也好,还是自己的GUI也好,我都不满意.MFC确实太复杂,以至于我手下的人很难掌握,跟别说在MFC的基础上扩展了,dotNet的效率实在不怎么地,自己的GUI也跟dotNet一样的表现(因为是一样的思路,紧紧因为传统的GUI绘制跟游戏绘制冲突).
所以,至今仍在思考,怎么能找到一个更好的解决方案.这主要体现在消息处理上.我对你现在的事件处理方式也不认同,map的查找可能很快了.但那个copy函数的存在让我很不爽.
同时提一个建议:能将graphics抽象出来是最好的,如果Windows的绘制能自己去实现,就不会有那么多游戏里重复实现的GUI库了。
lanzhengpeng2 2012-02-10
  • 打赏
  • 举报
回复
看了你的button的实现,看来是我理解错了.是我理解上有偏差.你的事件处理并非dotNet的代理模式.
但我没有看出来,我如何扩展自己的消息,如何扩展自己的widget,在不动现有的代码的情况下.

[Quote=引用 130 楼 jinhao 的回复:]
看得出来,这只是思维习惯的问题。相比之下,MFC在处理事件的时候,就首先需要确定要把消息投递到哪个类中,到最后,就会发现这个类多出了很多原本与该类无关的代码。
至于灵活度,这里有两种解释:一种叫原本不属于它的范畴,就需要做更多的事才能完成;另一种则只需要做很少的事就能完成。我的观点是MFC在这点并不灵活,只能说,看上去它更原始,以至于让人觉得什么都能做,而复杂度就另当别论了。

至于ON_……
[/Quote]
Jinhao 2012-02-09
  • 打赏
  • 举报
回复
我没完全明白你说的消息模式和代理模式在这里分别指什么,有点迷惑了.
另外button不需要为了处理事件而派生,简单的button在大多数情况也不需要派生.
Jinhao 2012-02-09
  • 打赏
  • 举报
回复
看得出来,这只是思维习惯的问题。相比之下,MFC在处理事件的时候,就首先需要确定要把消息投递到哪个类中,到最后,就会发现这个类多出了很多原本与该类无关的代码。
至于灵活度,这里有两种解释:一种叫原本不属于它的范畴,就需要做更多的事才能完成;另一种则只需要做很少的事就能完成。我的观点是MFC在这点并不灵活,只能说,看上去它更原始,以至于让人觉得什么都能做,而复杂度就另当别论了。

至于ON_COMMAND_RANGE也很容易实现,只要用同一个事件处理函数就能轻松完成,在内部判断一下窗口的句柄就行。不过我在105楼的回帖中给出了一种方案,甚至连句柄的判断都不需要,也就是在注册事件的时候,将需要的数据与事件处理函数绑定。
lanzhengpeng2 2012-02-09
  • 打赏
  • 举报
回复
Windows和MFC是基于消息模式的.你这个,dotNet的都是代理模式.
MFC复杂就复杂在,Windows的正常消息路由不能满足大型复杂的界面应用,MFC内部需要将消息路由到Frame/View/Document上.很多消息又需要反射回去给控件自己处理.
另外,Button的消息相应不见得就是Button的父窗口,这个是Windows的原始窗口做起来很困难的,MFC也把这些东西处理了.所以,导致MFC很负责.
但MFC的灵活程度还是非常高的.如果你熟悉那些消息处理宏,书写起来还是很方便快捷,有的时候比代理模式好用.如On Command Range

[Quote=引用 125 楼 jinhao 的回复:]
我没完全明白你说的消息模式和代理模式在这里分别指什么,有点迷惑了.
另外button不需要为了处理事件而派生,简单的button在大多数情况也不需要派生.
[/Quote]
jadedrip 2012-02-09
  • 打赏
  • 举报
回复
对标准库的友好是很好的,支持Unicode么?

加载更多回复(110)

24,852

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧