2017-01-18 20 views
0

У меня возникли проблемы с получением метки wxStaticText для динамического переноса в диалоговом окне с использованием wxWidgets 3.0.2. Я следовал идеям по другим вопросам, например, 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(); 
} 

Результата выглядит нормально, когда диалог первым показан, но при изменении размера узкими и резервное копирование, вы получите этот результат:

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: вызов 'Layout()' в диалоговом окне вызывает бесконечный цикл, если изменение размера связано с 'm_text'. Привязка к самому диалогу вызывает тот же эффект «храпового удара», который показан на скриншотах. – Inductiveload

ответ

1

Без какой-либо wrap(), wxStaticText отображает текст правильно (обертывание на границах слов), используя минимальный код в окнах с wx 3.0.2. Я могу изменить размер диалогового окна (сжиматься, расти), а 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); 
+0

Обсуждение проблемы X/Y. Спасибо! – Inductiveload

0

Встречалась аналогичная проблема. Я должен где-то хранить развернутое сообщение, когда размер wxStaticText изменен, установите сообщение и оберните вызов. иначе линия не может быть хорошо обернута.

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