使用Nana 0.8创建一个简单的记事本

本示例创建一个简单的记事本程序,这个简单的记事本可以让用户选择并打开文本文件。同时,也演示了如何使用place,menubar,menu,textbox,msgbox以及filebox。


示例中的程序是基于 Nana 0.8和C++11,因此需要使用GCC4.7或VS2013。

开始

首先,这里会贴出完整代码,然后解析其中的函数。

#include <nana/gui.hpp>
#include <nana/gui/widgets/menubar.hpp>
#include <nana/gui/widgets/textbox.hpp>
#include <nana/gui/place.hpp>
#include <nana/gui/msgbox.hpp>
#include <nana/gui/filebox.hpp>

using namespace nana;

class notepad_form
    : public form
{
public:
    notepad_form()
    {
        caption(L"Simple Notepad - Nana C++ Library");
        menubar_.create(*this);

        textbox_.create(*this);
        textbox_.borderless(true);
        API::effects_edge_nimbus(textbox_, effects::edge_nimbus::none);
        textbox_.enable_dropfiles(true);
        textbox_.events().mouse_dropfiles([this](const arg_dropfiles& arg) //感网友<span><span dir="ltr"><span style="font-family:Verdana;font-size:12px;color:black;"><span style="font-size:14px;"><span style="font-family:Calibri;"><span lang="en-US">TANG Zhenhao</span></span></span></span></span></span>指出arg_drppfiles的拼写错误。<span><strong></strong></span>
        {
            if (arg.files.size() && _m_ask_save())
                textbox_.load(arg.files.at(0).data());
        });

        _m_make_menus();

        place_.bind(*this);
        place_.div("vert<menubar weight=28><textbox>");
        place_.field("menubar") << menubar_;
        place_.field("textbox") << textbox_;
        place_.collocate();

        events().unload([this](const arg_unload& arg){
            if (!_m_ask_save())
                arg.cancel = true;
        });
    }
private:
    nana::string _m_pick_file(bool is_open) const
    {
        filebox fbox(*this, is_open);
        fbox.add_filter(L"Text", L"*.txt");
        fbox.add_filter(L"All Files", L"*.*");

        return (fbox.show() ? fbox.file() : nana::string());
    }

    bool _m_ask_save()
    {
        if (textbox_.edited())
        {
            auto fs = textbox_.filename();
            msgbox box(*this, L"Simple Notepad", msgbox::button_t::yes_no_cancel);
            box << L"Do you want to save these changes?";

            switch (box.show())
            {
            case msgbox::pick_yes:
                if (fs.empty())
                {
                    fs = _m_pick_file(false);
                    if (fs.empty())
                        break;
                    if (fs.find(L".txt") == fs.npos)
                        fs += L".txt";
                }
                textbox_.store(fs.data());
                break;
            case msgbox::pick_no:
                break;
            case msgbox::pick_cancel:
                return false;
            }
        }
        return true;
    }

    void _m_make_menus()
    {
        menubar_.push_back(L"&FILE");
        menubar_.at(0).append(L"New", [this](menu::item_proxy& ip)
        {
            if(_m_ask_save())
                textbox_.reset();
        });
        menubar_.at(0).append(L"Open", [this](menu::item_proxy& ip)
        {
            if (_m_ask_save())
            {
                auto fs = _m_pick_file(true);
                if (fs.size())
                    textbox_.load(fs.data());
            }
        });
        menubar_.at(0).append(L"Save", [this](menu::item_proxy&)
        {
            auto fs = textbox_.filename();
            if (fs.empty())
            {
                fs = _m_pick_file(false);
                if (fs.empty())
                    return;
            }
            textbox_.store(fs.data());
        });

        menubar_.push_back(L"F&ORMAT");
        menubar_.at(1).append(L"Line Wrap", [this](menu::item_proxy& ip)
        {
            textbox_.line_wrapped(ip.checked());
        });
        menubar_.at(1).check_style(0, menu::checks::highlight);
    }
private:
    place   place_;
    menubar menubar_;
    textbox textbox_;
};

int main()
{
    notepad_form npform;
    npform.show();
    exec();
}

_m_pick_file()

我们以这个私有函数开始分析代码,该函数的作用是弹出文件选择框,让用户选择一个文件

return (fbox.show() ? fbox.file() : nana::string());
如果用户点击了 取消 按钮 或者 关闭文件选择框,fbox.show()就返回false表示没有选择文件。


_m_ask_save()

该函数会在关闭文本的时候询问用户用户是否保存到文件。

if(textbox_.edited())
判断文本是否被用户编辑过。如果被编辑过,那么

auto fs = textbox_.filename();
当编辑框打开或者保存文件的时候,文本编辑框会保留这个文件名。如果字符串fs为空,程序就会询问用户选中一个文件来保存文本。

_m_ask_save()函数有一个bool类型返回值,如果它返回false表示用户取消了选择。


notepad_form()

在默认构造函数中,我们需要创建菜单栏和文本框,然后为这些widget设置布局。

textbox_.borderless(true);
API::effects_edge_nimbus(textbox_, effects::edge_nimbus::none);
取消文本框的边框及效果

textbox_.enable_dropfiles(true);
textbox_.events().mouse_dropfiles([this](const arg_drppfiles& arg)
{
    if (arg.files.size() && _m_ask_save())
        textbox_.load(arg.files.at(0).data());
});
为文本框设置拖拽事件,这样用户就能将程序外面的文本文件拖入程序中。这里调用_m_ask_save()是为了询问用户将先前编辑的文本保存。

events().unload([this](const arg_unload& arg){
    if (!_m_ask_save())
        arg.cancel = true;
});
设置一个窗口关闭事件,它可以使程序在退出前询问用户是否保存编辑的文本,并且用户也可以取消关闭程序。


_m_make_menus()

为菜单栏设置菜单。


int main()

创建记事本的窗口。




已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页