【问题标题】:wxWidgets C++ - dynamically wrapping wxStaticText in dialogwxWidgets C++ - 在对话框中动态包装 wxStaticText
【发布时间】:2017-01-18 03:26:03
【问题描述】:

我无法使用 wxWidgets 3.0.2 在对话框中动态包装wxStaticText 标签。我遵循了其他问题的想法,例如this one,有点我仍然有奇怪的效果。

我在文本上使用Wrap(int) 函数,在wxEVT_SIZE 事件的回调中,但它似乎对文本产生了意想不到的影响,而且似乎只是“棘轮”减小了大小,并且窗口展开时不会再次换行。

绑定的主要部分是:

CTOR(...) {
    ....
    m_text->Bind(wxEVT_SIZE, &DIALOG_WRAPTEXT::onResize, this);
}

void CLASS::onResize( wxSizeEvent& event )
{
    m_text->Wrap( event.GetSize().GetWidth() );
    event.Skip();
}

第一次显示对话框时结果看起来不错,但是当您缩小并备份时,您会得到以下结果:

一个最小可重现的例子是:

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif
class DIALOG_WRAPTEXT: public wxDialog
{
public:

    DIALOG_WRAPTEXT( wxWindow* parent,
            const wxString& aTitle, const wxSize aSize );

private:

    void onResize( wxSizeEvent& evt );

    wxBoxSizer* m_itemBoxSizer;
    wxStaticText* m_text;
};

DIALOG_WRAPTEXT::DIALOG_WRAPTEXT(
        wxWindow* parent, const wxString& aTitle, const wxSize aSize ):
                    wxDialog( parent, wxID_ANY, aTitle,
                                 wxPoint( -1, -1 ), aSize,
                                 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
    m_itemBoxSizer = new wxBoxSizer( wxVERTICAL );
    SetSizer( m_itemBoxSizer );

    wxString msg("Lots and lots of text to wrap hopefully. "
                "Lots and lots of text to wrap hopefully. "
                "Lots and lots of text to wrap hopefully. "
                "Lots and lots of text to wrap hopefully. "
                "Lots and lots of text to wrap hopefully. "
                "Lots and lots of text to wrap hopefully. "
                );

    m_text = new wxStaticText( this, wxID_ANY, msg );
    // wxEXPAND makes no difference
    m_itemBoxSizer->Add( m_text, 1, wxALIGN_TOP | wxALL | wxEXPAND, 5 );

    // Bind to m_text or this, same effect
    m_text->Bind(wxEVT_SIZE, &DIALOG_WRAPTEXT::onResize, this);

}

void DIALOG_WRAPTEXT::onResize( wxSizeEvent& event )
{
    //m_text->Freeze(); // makes no difference
    const auto w = event.GetSize().GetWidth();
    wxLogDebug( "Wrap to width: %d",w ); // produces sensible values
    m_text->Wrap( w );
    //m_text->Thaw();
    event.Skip();
}


class MyApp: public wxApp
{
public:

    bool OnInit() override
    {
        auto d = new DIALOG_WRAPTEXT(NULL, "Dialog title", wxSize(200, 200));

        d->ShowModal();
        d->Destroy();
    }
};

wxIMPLEMENT_APP(MyApp);

在对话框中动态包装静态文本的正确方法是什么?

【问题讨论】:

  • 您是否尝试在设置新的换行值后在对话框中调用Layout();
  • @erg:如果调整大小绑定到m_text,则在对话框上调用Layout() 会导致无限循环。绑定到对话框本身会导致屏幕截图中显示的相同“棘轮向下”效果。

标签: c++ dialog wxwidgets word-wrap


【解决方案1】:

没有任何 wrap(),wxStaticText 使用 wx 3.0.2 的 windows 上的以下最小代码正确显示文本(在单词边界处换行)。我可以调整对话框的大小(缩小、放大),wxStaticText 将正确更新自身。这对您的用例来说还不够吗?您确定需要使用 wrap 功能吗?

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
class DIALOG_WRAPTEXT : public wxDialog
{
public:

    DIALOG_WRAPTEXT(wxWindow* parent,
        const wxString& aTitle, const wxSize aSize);

private:

    void onResize(wxSizeEvent& evt);

    wxBoxSizer* m_itemBoxSizer;
    wxStaticText* m_text;
};

DIALOG_WRAPTEXT::DIALOG_WRAPTEXT(
    wxWindow* parent, const wxString& aTitle, const wxSize aSize) :
    wxDialog(parent, wxID_ANY, aTitle,
        wxPoint(-1, -1), aSize,
        wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
    m_itemBoxSizer = new wxBoxSizer(wxVERTICAL);
    SetSizer(m_itemBoxSizer);

    wxString msg("Lots and lots of text to wrap hopefully. "
        "Lots and lots of text to wrap hopefully. "
        "Lots and lots of text to wrap hopefully. "
        "Lots and lots of text to wrap hopefully. "
        "Lots and lots of text to wrap hopefully. "
        "Lots and lots of text to wrap hopefully. "
    );

    m_text = new wxStaticText(this, wxID_ANY, msg);
    // wxEXPAND makes no difference
    m_itemBoxSizer->Add(m_text, 1, wxALIGN_TOP | wxALL | wxEXPAND, 5);

    // Act on dialog resize
    Bind(wxEVT_SIZE, &DIALOG_WRAPTEXT::onResize, this);

}

void DIALOG_WRAPTEXT::onResize(wxSizeEvent& event)
{
    // layout everything in the dialog
    Layout();
    event.Skip();
}


class MyApp : public wxApp
{
public:

    bool OnInit() override
    {
        auto d = new DIALOG_WRAPTEXT(NULL, "Dialog title", wxSize(200, 200));

        d->ShowModal();
        d->Destroy();

        return true;
    }
};

wxIMPLEMENT_APP(MyApp);

【讨论】:

  • 谈谈 X/Y 问题。谢谢!
【解决方案2】:

遇到了类似的问题。我必须将未包装的消息存储在某处,当 wxStaticText 调整大小时,设置消息并调用 wrap。否则线可能不会被很好地包裹。

void MyFrame::onResize(wxSizeEvent& evt)
{
const auto w = evt.GetSize().GetWidth();
m_text->SetLabel(m_msg); // unwrapped message
m_text->Wrap(w);
evt.Skip();
}

【讨论】:

  • 对我来说 setlabel 是不必要的
猜你喜欢
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2014-07-22
相关资源
最近更新 更多