Menu

Nana Tutorial: Creating A GUI Calculator

Requires: C++11, Nana 0.8
In this tutorial, we will make a GUI calculator with Nana C++ Library. The calculator that we build will look like:

Screenshot of Calculator

Using nana::place which is introduced into Nana in the version of 0.5, we can create a such GUI easily.

Let's start the code.

:::C++
#include <nana/gui.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/place.hpp>

using namespace nana;

struct stateinfo
{
    enum class state{init, operated, assigned};

    state   opstate{state::init};
    wchar_t operation{L'+'};
    double oprand{0};
    double outcome{0};
    label & procedure;
    label & result;

    stateinfo(label& proc, label& resl)
        : procedure(proc), result(resl)
    {}
};

//Omit the definitons at this point.
//Full definitions in calculator.cpp
//handle the number keys
void numkey_pressed(stateinfo& state, const arg_mouse& arg);

//handle the non-number keys
void opkey_pressed(stateinfo& state, const arg_mouse& arg);

int main()
{
    form fm;
    fm.caption(STR("Calculator"));

    //Use class place to layout the widgets.
    place place(fm);
    place.div(  "vert<procedure weight=10%><result weight=15%>"
        "<weight=2><opkeys margin=2 grid=[4, 5] gap=2 collapse(0,4,2,1)>");

    label procedure(fm), result(fm);

    //Make the label right aligned.
    procedure.text_align(nana::align::right);
    result.text_align(nana::align::right);
    result.typeface(nana::paint::font(nullptr, 14, true));

    place.field("procedure")<<procedure;
    place.field("result")<<result;

    stateinfo state(procedure, result);
    std::vector<std::unique_ptr<nana::button>> op_keys;

    wchar_t keys[] = L"C\261%/789X456-123+0.=";
    nana::paint::font keyfont(nullptr, 10, true);
    for(auto key : keys)
    {
        op_keys.emplace_back(new button(fm));
        op_keys.back()->caption(string(1, key));
        op_keys.back()->typeface(keyfont);

        if('=' == key)
        {
            op_keys.back()->background(0x7ACC);
            op_keys.back()->foreground(0xFFFFFF);
        }
        place.field("opkeys") << *op_keys.back();

        //Make event answer for keys.
        if(('0' <= key && key <= '9') || ('.' == key))
            op_keys.back()->events().click.connect(std::bind(numkey_pressed, std::ref(state), std::placeholders::_1));
        else
            op_keys.back()->events().click.connect(std::bind(opkey_pressed, std::ref(state), std::placeholders::_1));
    }

    place.collocate();
    fm.show();
    exec();
}

To get entire code of calculator, please refer to calculator.cpp

Please refer to the documentation for the details of class place

Posted by Jinhao 2013-03-03 Labels: C++11 Nana GUI
  • ptolomey

    ptolomey - 2013-03-07

    Hi, Jinhao.
    Very impressive introduction.
    The code is much clearer and shorter than in other competitors cross-platforms GUIs, like WXwidgets.
    Thank you for the great product.

     
    • Jinhao

      Jinhao - 2013-03-07

      Hi, Ptolomey
      Thanks for your comment.
      I am still working on planning how to make this more than an incubation project, so I really desire feedbacks to help me improve this library! :-)

      Thanks,
      Jinhao

       
      • Anonymous

        Anonymous - 2014-04-01

        你好,这个demo我在VS2013中编译通不过,报make_event调用二义性,之前用VS2012编译好像是能通过的,这是什么原因,可能是C++11标准中不支持,还是VS2013对C++标准实现不够造成,还是这个nana库的Bug,还是我哪个细节没处理好?我感觉应该是VS2013编译器不完善……

         
    • Anonymous

      Anonymous - 2014-04-01

      ……

       

      Last edit: Anonymous 2014-04-01
  • Anonymous

    Anonymous - 2013-07-03

    您好,using namepsace拼写错了.这是c++11的demo吗?在vs2010下跑不过啊

     
    • Jinhao

      Jinhao - 2013-07-04

      是C++11的demo,需要VC2012或以上的。也可以用MinGW 4.7编译。感谢指出错误。

       
  • Anonymous

    Anonymous - 2021-08-26

    编译后exe文件体积感人

     
  • Anonymous

    Anonymous - 2023-02-20

    大佬,这个项目还开发维护么

     

Anonymous
Anonymous

Add attachments
Cancel