首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

Nana C++ Library:2012年新年快乐,该怎么处理

2013-01-09 
Nana C++ Library:2012年新年快乐尽管C++是一门强大且语法灵活的语言,实际上,许多程序员并不喜欢用C++开发

Nana C++ Library:2012年新年快乐
尽管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界面库。

欢迎各种意见和建议!共同探讨!
[解决办法]
顶,学习下
[解决办法]

想了解下,撇开跨平台不说。
与MFC,WTL比较,有什么优势?
[解决办法]
界面全靠代码来生成?
没有界面编辑器?
------解决方案--------------------


支持:)
[解决办法]
支持下
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
的确编辑器不好,友情UP~!
[解决办法]
学习 学习
[解决办法]
是不是有点像 QT 。
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
很好。。。。
[解决办法]
lzv5 lz87Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
我试过了,很不错。。。。。。。。。不错
[解决办法]
LZ厉害啊
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
自己写的吗?  study......
[解决办法]
看起来相当有吸引力!强力支持。
[解决办法]
楼主威武!Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
楼主威武,开源万岁
[解决办法]
我还以为是Nehe呢,呵呵
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理这代码简洁的有点凶残了。。。
[解决办法]
支持一下,GUI简单既是美。
[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理
[解决办法]
上次下载了没用配置起来
配置好的 有没有的
[解决办法]
我添加 Shell32.lib 
可以编译通过了,谢谢
[解决办法]
顶,长点见识
[解决办法]
先用下win32的,其实我想在linux下用,最好能在android下用。。。
[解决办法]
试了下发现vs2010的 Click the Tools menu>>Options>>Projects and Solutions>>VC++ Directories>> 已经无效,要添加头文件要放到项目属性里了。或者直接把include里面的nana文件夹放vc安装目录的include下。
[解决办法]
支持对象的反射吗?也就是类似mfc中的对象自动生成。类似 class = createobject("objectname");
[解决办法]
反射很重要,当需要将界面布局保存为xml文件的时候,恢复后肯定都是类的名字字符串。

支持将界面布局保存起来的特性能够开发出功能很强大、灵活、界面布局与代码解耦的程序。

我现在的程序的界面布局甚至可以开放给用户自己拖动来组合,然后保存为界面模板,让用户



可以随时改变布局模板。因此,界面布局对我的程序来说不需要改动任何,只需要拖动鼠标。
[解决办法]
你上面那个例子只能处理编译期的反射,不能处理运行期的类型反射把。
[解决办法]
hi, Jinhao,

看了你在c++.moderated的帖子和一些人的留言,我有几个问题,那就是,

对于市场上已经有了wxWidget, qt,甚至fltk等的跨平台工具,nana有什么优势呢?虽然不同的工具有其弱点,但是如果一个新的工具想要有人用的话,就要有一些独有的优势,以及不能比其他工具有明显的缺点。

第二,你对nana以后的发展是否有一些思路呢?例如mac的支持?相信其他的gui工具库都是支持mac的。例如对手机系统的支持?qt已经有了iphone port和android port,虽然不是官方的。加上wp8很可能开放native code support,相信qt也很有理由支持wp8。

如果人们看不到一个前景话,就很难去用这个工具,特别是opensource的东西经常都死在半路。

也许你对这些问题都有一个很清楚的思考,但是从你的帖子和文档里没有发现这些问题的答案。一个新的工具需要很多人用,才会有人contribute进来,才会真正的发展。要想有人用,希望你对这些问题有一些详细的思考。你自己要有信心,用户才会有信心。

我是很希望c++有一个好用的gui库的。wxWidget是我最欣赏的库,可惜太臃肿了。希望Nana能有一个好的发展。

记得Stroustrup曾经说过,C++标准并没有gui库当成重点,主要原因是gui变化实在太快了,同时 "Anyway, the standards committee do not have the resources to build a new and better GUI. "

楼主加油哇。
[解决办法]

引用:
我考虑过这个问题,想加入一种描述用的脚本。只是现阶段来说,这不算是重点,因为库还没完善。
另外还有一个重要的因素让我觉得不应该考虑这个问题。这并不需要由这个界面库来支持,其他C++程序员也许会有自己的方案,甚至更好的方案,只要与这个库一起工作就能满足他们的需要。

哈哈,这个想法不错。

话说,MediaWiki 准备内嵌 Lua 作为排版语言了。。。
[解决办法]
事件响应机制清晰,简单,代码规模较小,线程安全是亮点!,就是不知道当程序员想改变默认控件的样式的时候(也就是自绘)方不方便?
[解决办法]
楼上,自绘很方便的。只要新创建一个xx_drawer类,实现 draw_border等等的member function,实现mouse click等等的gui显示,就可以了。。稍微看了一下,nana应该本身就是自绘的,和qt/fltk类似。
[解决办法]
也能,只是需要一个预先“注册”的动作。只有注册了的才能 根据类名创建。

这个要注册多少呀,而且在派生类的自注册上不太现实。

==========
我曾经用宏实现过,宏的链接字符串属性可以搞定。
[解决办法]
还是不支持!
[解决办法]
引用:
嘿嘿,我也考虑过弄个什么叫本语言。结果被那群人鄙视了。理由就是,美工/ui设计拒绝学习脚本语言


错,分工要清楚。不想兼职写脚本的就像纯美工前端,负责界面的就是 HTML + CSS + 切图,JS 归 JS。
[解决办法]
所以这这个核心外面包装的时候,描述语言和逻辑控制一定要分开

[解决办法]
如果你不告菜鸟需要包含include文件夹,他们不会编译的。
如果你不告诉我怎么把控制台的黑框弄掉,我会生气的。
[解决办法]
引用:
如果你不告菜鸟需要包含include文件夹,他们不会编译的。
如果你不告诉我怎么把控制台的黑框弄掉,我会生气的。


加windows.h 头文件 使用 winmain 就图形了
GCC 不用 添加shell32,可能自动添加了 
VC10编译器 要shell32.lib

使用 gcc version 4.6.1 (tdm-1) 编译提示错误 
R:/nana/include/nana/detail/functor_invoker_5.hpp:70:22: error: reference 'obj_'
 cannot be declared 'mutable' [-fpermissive]
gmake: *** [../bin/dev-cpp/drawing.o] Error 1


Makefile 文件 CXXINCS 改成如下,可以编译成库文件
CXXINCS =  -I"R:/nana/include" -fpermissive

nana/include 没有放GCC目录下,所以要指定目录, 加上 -fpermissive 忽然到错误
使用编译好的 nana.a 也要增加 -fpermissive

------解决方案--------------------


VC6的编译器为何不支持呢
[解决办法]
error C2871: 'nana::gui' : a namespace with this name does not exist
这个bug俺以前请教过您的。
Nana C++ Library:2012年新年快乐,该怎么处理
//Error duo to VC2010 bug
个人建议这个列表加一下官方的描述。
Nana C++ Library:2012年新年快乐,该怎么处理
 
[解决办法]
恩,感觉挺好。。。
[解决办法]
在已损坏了程序内部状态的 j.exe 中发生了缓冲区溢出。按“中断”以调试程序,或按“继续”以终止程序。

有关更多详细信息,请参见“帮助”主题“如何调试缓冲区溢出问题”。


配置好后 为什么这样??
[解决办法]


[解决办法]
现在不流行 visual 了吗??都开始纯手工代码了!!!

[解决办法]
Nana C++ Library:2012年新年快乐,该怎么处理看看
[解决办法]
哈哈,标记一下,这两天没事的时候,玩玩。
[解决办法]
不错,有点新意。不过事物总会有矛盾两方面的,你追求代码简洁就会丧失效率,追求效率就会导致代码复杂。这要看你的库定位在哪里,如果是较轻量的GUI程序的话还是不错的。
[解决办法]
赞一下。
[解决办法]
测试代码如下:

#include "stdafx.h"
#include <nana/gui/wvl.hpp>
#include <nana/gui/widgets/label.hpp>

using namespace nana::gui;

int APIENTRY _tWinMain(HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPTSTR    lpCmdLine,
   int       nCmdShow)
{
form fm;
label lb(fm, 0, 0, fm.size().width, fm.size().height);
lb.caption(STR("Hello, World!"));
fm.show();
exec();
return 0;
}

[解决办法]
引用:
引用:

测试代码如下:
C/C++ code

#include "stdafx.h"
#include <nana/gui/wvl.hpp>
#include <nana/gui/widgets/label.hpp>

using namespace nana::gui;

int APIENTRY _tWinMain(HINST……

这样做我想应该不太靠谱(如果这样做的话,我这边实际也未编译通过);
首先nana编译静态库的设置不能是/MTd或/MT(目前实际也不是),因为如果这样做的话,nana编译出来的静态库就包含部分c runtime中的符号,接下来我的测试程序,不管是采用/MTd还是/MDd编译设置,在链接时必然会报符号重定义的错误(测试程序肯定也会需要用到c runtime中的部分符号,这样有些符号就会在2个地方都存在);
其次当我把debug下nana的工程配置:basic runtime checks设置为default时,重新编译后,运行就不报错了,google了下basic runtime checks的具体作用后,我猜nana的代码是不是某些地方存在缓存区可能溢出的问题?!

[解决办法]
我的是vc9!
[解决办法]
我这边调试跟踪了下,发现堆栈溢出错误源于:
nana\source\detail\platform_spec.cpp:113行,SystemParametersInfo API操作获取失败;


这样metrics.lfMessageFont.lfFaceName数组在make_native_font中拷贝时就会造成堆栈溢出;

[解决办法]


//Create default font object.
NONCLIENTMETRICS metrics;
#ifdef WINVER && (WINVER >= 0x0600)
metrics.cbSize = sizeof metrics - sizeof metrics.iPaddedBorderWidth;
#else
metrics.cbSize = sizeof metrics;
#endif
bool bResult = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0);
const nana::char_t* lfFaceName = NULL;
if (bResult)
{
lfFaceName = metrics.lfMessageFont.lfFaceName;
}
def_font_ref_ = make_native_font(lfFaceName, font_size_to_height(9), 400, false, false, false);

我这边这样改了下,就没问题了;
PS:参考了http://hi.baidu.com/guid/blog/item/5d9e019535169f007af4806a.html;
[解决办法]
不好意思,上面代码宏定义处使用有问题,应该如下:

//Create default font object.
NONCLIENTMETRICS metrics;

#ifdef WINVER
#if WINVER >= 0x0600
metrics.cbSize = sizeof metrics - sizeof metrics.iPaddedBorderWidth;
#else
metrics.cbSize = sizeof metrics;
#endif
#else
metrics.cbSize = sizeof metrics;
#endif

bool bResult = ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof metrics, &metrics, 0);
const nana::char_t* lfFaceName = NULL;
if (bResult)
{
lfFaceName = metrics.lfMessageFont.lfFaceName;
}
def_font_ref_ = make_native_font(lfFaceName, font_size_to_height(9), 400, false, false, false);

[解决办法]
我靠。我自己也写了个GUI库。自以为很面向对象。跟你这一比简直自惭形秽。佩服佩服。
还有。跨平台部分参考了AGG吧?呵呵。
[解决办法]
引用:
>>在链接时必然会报符号重定义的错误。
不会发生这种情况,生成lib不会和crt发生链接。

你是对的,我想岔了,脑残了!
[解决办法]
翻页。。

热点排行