wxWidgets C++ - 在对话框中动态地包装wxStaticText

问题描述:

我在使用wxWidgets 3.0.2获取wxStaticText标签在对话框中动态包装时遇到问题。我遵循其他问题的想法,如this one,我仍然有奇怪的影响。wxWidgets C++ - 在对话框中动态地包装wxStaticText

我使用上的文字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(); 
} 

结果看起来OK时,第一个显示的对话框,但是当你调整窄,备份,你会得到这样的结果:

After making narrower After making wide again

最小再现的例子是:

#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); 

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

+0

您是否在设置新的换行值后尝试在对话框中调用'Layout();'? – erg

+0

@erg:如果resize被绑定到'm_text',那么在对话框中调用'Layout()'会导致无限循环。绑定到对话框本身会导致屏幕截图中显示的相同“棘轮效应”效果。 – Inductiveload

没有任何wrap(),wxStaticText使用wx 3.0.2在windows上使用下面的最小代码正确显示文本(在文字边界环绕)。我可以调整对话框大小(缩小,增大),wxStaticText会自行更新。这对于您的用例来说还不够?你确定你需要使用包装功能吗?

#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); 
+0

谈谈X/Y问题。谢谢! – Inductiveload

遇到类似的问题。我必须将解包的消息存储在某处,当调整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(); 
}