首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ Nana如何从全局列表框*指针中访问索引0中的按钮?

C++ Nana如何从全局列表框*指针中访问索引0中的按钮?
EN

Stack Overflow用户
提问于 2017-07-20 09:59:32
回答 2查看 573关注 0票数 1

我有一个listbox,在第一列中,它包含一个带有buttontext字段。

我有一个指向nana listBox的全局指针

代码语言:javascript
复制
listbox*                listBox = nullptr;

我从class中检索了这个这里

代码语言:javascript
复制
#include <nana/gui.hpp>
#include <nana/gui/widgets/label.hpp>
#include <nana/gui/widgets/button.hpp>
#include <nana/gui/widgets/listbox.hpp>
#include <nana/gui/widgets/textbox.hpp>

#include <nana/gui/wvl.hpp> 
#include <nana/system/platform.hpp>

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <Windows.h>

using namespace nana;

//Creates a textbox and button
//textbox shows the value of the sub item
//button is used to delete the item.
class inline_widget : public listbox::inline_notifier_interface
{
private:
    //Creates inline widget
    //listbox calls this method to create the widget
    //The position and size of widget can be ignored in this process
    virtual void create(window wd) override
    {
        //Create listbox
        txt_.create(wd);
        txt_.events().click([this]
        {
            //Select the item when clicks the textbox
            indicator_->selected(pos_);
        });

        txt_.events().mouse_move([this]
        {
            //Highlight the item when hovers the textbox
            indicator_->hovered(pos_);
        });

        txt_.events().key_char([this](const arg_keyboard& arg)
        {
            if (arg.key == keyboard::enter)
            {
                //Modify the item when enter is pressed
                arg.ignore = true;
                indicator_->modify(pos_, txt_.caption());
            }
        });
        //Or modify the item when typing
        txt_.events().text_changed([this]()
        {
            indicator_->modify(pos_, txt_.caption());
        });
        //Create button
        btn_.create(wd);
        btn_.caption("Start");
        btn_.enabled(false);
        btn_.events().click([this]
        {
            //Delete the item when button is clicked
            auto & lsbox = dynamic_cast<listbox&>(indicator_->host());
            //buttonPressed(btn_, pos_.item);
        });

        btn_.events().mouse_move([this]
        {
            //Highlight the item when hovers the button
            indicator_->hovered(pos_);
        });
    }

    //Activates the inline widget, bound to a certain item of the listbox
    //The inline_indicator is an object to operate the listbox item,
    //pos is an index object refers to the item of listbox
    virtual void activate(inline_indicator& ind, index_type pos)
    {
        indicator_ = &ind;
        pos_ = pos;
    }

    void notify_status(status_type status, bool status_on) override
    {
        //Sets focus for the textbox when the item is selected
        if ((status_type::selecting == status) && status_on)
            txt_.focus();
    }

    //Sets the inline widget size
    //dimension represents the max size can be set
    //The coordinate of inline widget is a logical coordinate to the sub item of listbox
    void resize(const size& dimension) override
    {
        auto sz = dimension;
        sz.width -= 50;
        txt_.size(sz);

        rectangle r(sz.width + 5, 0, 45, sz.height);
        btn_.move(r);
    }

    //Sets the value of inline widget with the value of the sub item
    virtual void set(const value_type& value)
    {
        //Avoid emitting text_changed to set caption again, otherwise it
        //causes infinite recursion.
        if (txt_.caption() != value)
            txt_.caption(value);
    }

    //Determines whether to draw the value of sub item
    //e.g, when the inline widgets covers the whole background of the sub item,
    //it should return false to avoid listbox useless drawing
    bool whether_to_draw() const override
    {
        return false;
    }

private:
    inline_indicator * indicator_{ nullptr };
    index_type pos_;
    textbox txt_;
    button btn_;
};

这是我的thread

代码语言:javascript
复制
void theThread()
{
    while (1)
    {
        //How can I access a button on index 0 from my listbox?
        button* mybutton = listBox.at(0). ... ? -->HOW CAN I DO THIS?
        mybutton->caption("I did it!!");
        Sleep(1000);
    }
}

我的main()函数:

代码语言:javascript
复制
void main()
{
    using namespace nana;
    form fm(nana::API::make_center(750, 500), appear::decorate<appear::taskbar>());


    listbox lsbox(fm, rectangle{ 10, 50, 700, 200 });

    listBox = &lsbox;

    //Create columns
    lsbox.append_header("Col1");
    lsbox.append_header("Col2");
    lsbox.append_header("Col3");
    lsbox.append_header("Col4");
    lsbox.append_header("Col5");

    lsbox.at(0).append({ "text1", "text2", "text3", "text4", "text5" });
    lsbox.at(0).append({ "text1", "text2", "text3", "text4", "text5" });
    lsbox.at(0).append({ "text1", "text2", "text3", "text4", "text5" });

    lsbox.column_at(0).width(200);

    lsbox.at(0).inline_factory(0, pat::make_factory<inline_widget>());

    fm.show();


    std::thread myThread(theThread);

    exec();

    myThread.join();

}

问题:

如何从全局button指针访问位于listbox中的索引0上的listbox*

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-21 17:36:12

您正在尝试复杂地使用nana::listbox (或在维基中)最复杂的特性,这是Nana中最复杂的小部件。

据我所知,您不直接将内联小部件“附加”到列表中的每个项目。相反,列表本身会生成数量有限的小部件,并且在每一刻都会将其中的一个部件“内联”到每个小部件中,并且只对每个可见项进行“内联”。为了做到这一点,列表需要知道如何创建小部件,如何“更新”每个项,以及小部件如何响应不同的可能事件,以及如何更新相应的项。

这是通过将实现虚拟接口listbox::inline_notifier_interface的对象的“工厂”附加到列表的一个类别之一的列上来实现的。这就是您使用列表框类别的功能的地方

代码语言:javascript
复制
void nana::listbox::cat_proxy::inline_factory (size_type column,                    
               pat::cloneable<pat::abstract_factory<inline_notifier_interface>> factory);

这就解释了为什么没有一种直接的方式来访问内联小部件。也许可以在列表框中实现一个新的接口函数--我们将尝试。我看上去有一个私有函数inline_pane * _m_get_inline_pane(const category_t& cat, std::size_t column_pos) const,它返回一个inline_pane,它包含一个std::unique_ptr<inline_notifier_interface> inline_ptr;,您可以测试它是否为空,以及可以使用哪个std::unique_ptr<inline_notifier_interface> inline_ptr;来引用您的按钮。到目前为止,影响内联小部件的预期方法是更改相应项的内容,并使用inline_notifier_interface来反映该更改。

至于在创建时将对按钮的引用保存到全局向量中的解决方法,您可能更喜欢全局向量inline_widget,因为它包含一个index_type pos_;,您可以使用该index_type pos_;搜索当前链接到感兴趣项的元素。当然,您将很难确保向量指向活动对象。

您可能需要注意,访问item_proxy的方法是使用lsbox.at(0).at(item_number)lsbox.at(index_pair(0,item_number))

票数 1
EN

Stack Overflow用户

发布于 2017-07-21 12:30:09

我知道这不是最好的做法,但现在是这样的:

使用pointersbuttons创建了一个buttons

代码语言:javascript
复制
std::vector<button*>    mButtons;

关于button的创建,我push_back()引用vector

代码语言:javascript
复制
    //Create button
    btn_.create(wd);
    btn_.caption("Start");
    btn_.enabled(false);
    btn_.events().click([this]
    {
        //Delete the item when button is clicked
        auto & lsbox = dynamic_cast<listbox&>(indicator_->host());
        //lsbox.erase(lsbox.at(pos_));
        buttonPressed(btn_, pos_.item);
    });

    btn_.events().mouse_move([this]
    {
        //Highlight the item when hovers the button
        indicator_->hovered(pos_);
    });

    mButtons.push_back(&btn_); // <--------- here

现在我可以从外部控制buttons了。

代码语言:javascript
复制
button* btn = mButtons[index];
if (nullptr != btn)
{
    ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45211441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档