wxWidgets的文本换行会导致文本消失

编程语言 2026-07-09

我想做一个非常简单的聊天客户端,作为概念验证,因此决定使用wxWidgets。我的系统是CachyOS,基于GTK。所用的wxWidgets版本是 "3.3.3"。聊天客户端需要正确显示消息,因此在调整窗口大小时,文本应能正确换行,以便在需要调整聊天窗口大小时仍能正常显示。

#include <wx/wx.h>  
#include <wx/event.h>  
#include <wx/gdicmn.h>  
#include <wx/sizer.h>  

class MyApp : public wxApp  
{  
public:  
    virtual bool OnInit();  
};  

wxIMPLEMENT_APP(MyApp);  

class ClientFrame : public wxFrame  
{  
public:  
    ClientFrame(const wxString &title, const wxPoint &pos, const wxSize &size);  

    void OnSize(wxSizeEvent& ev);  

    wxStaticText* text;  
    wxSizer* sizer;  
};  

ClientFrame::ClientFrame(const wxString &title, const wxPoint &pos, const wxSize &size)  
    : wxFrame(NULL, wxID_ANY, title, pos, size)  
{  
    Bind(wxEVT_SIZE, &ClientFrame::OnSize, this);  

    text = new wxStaticText(this, wxID_ANY, "..... very very long text .................. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");  

    sizer = new wxBoxSizer(wxVERTICAL);  
    sizer->Add(text, 1, wxEXPAND | wxALL, 5);  
    sizer->SetMinSize(wxSize(720, 1080));  

    SetSizer(sizer);  
}  

void ClientFrame::OnSize(wxSizeEvent& ev)  
{  
    text->Wrap(ev.GetSize().GetWidth());  
}  

bool MyApp::OnInit()  
{      
    ClientFrame*  
    frame = new ClientFrame("example", wxDefaultPosition, wxDefaultSize);  
    frame->Show();  
    return true;  
}

这个示例应该能重现我的问题。当我把窗口设为全屏或只是把窗口变大时,文本本应换行并正常显示。但在这里,它却消失了。此外,文本有时还可能会溢出窗口。

我在网上到处搜寻,试着调整sizer、改变布局,呃……我唯一的猜测是这可能是GTK的问题。我真希望知道原因是什么,至少知道该去哪里排查。

解决方案

至少从初步看来,这像是wxWidgets某处的一个bug,尽管我还没有深入到能弄清楚具体位置的程度。不过解决它似乎相当容易。

我添加了注释,说明我为让它工作所做的改动。标记为 change #3 的那一项才是真正关键。前两个只是为了让那一项更容易实现,最后一个只是让显示稍微整洁一些(但应该进一步清理,至少去掉硬编码的数字)。

#include <wx/wx.h>
#include <wx/event.h>
#include <wx/gdicmn.h>
#include <wx/sizer.h>

class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};

wxIMPLEMENT_APP(MyApp);

class ClientFrame : public wxFrame
{
public:
    ClientFrame(const wxString &title, const wxPoint &pos, const wxSize &size);

    void OnSize(wxSizeEvent& ev);

    wxStaticText* text;
    wxSizer* sizer;

    // Change 1: for convenience later, save the label in a variable:   
    wxString label = "..... very very long text .................. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
};

ClientFrame::ClientFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
    : wxFrame(NULL, wxID_ANY, title, pos, size)
{
    Bind(wxEVT_SIZE, &ClientFrame::OnSize, this);

    // change #2: use the variable when creating the wxStaticText
    text = new wxStaticText(this, wxID_ANY, label);

    sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(text, 1, wxEXPAND | wxALL, 5);

    SetSizer(sizer);
}

void ClientFrame::OnSize(wxSizeEvent& ev)
{
    // change #3: set the label just before calling wrap():
    text->SetLabel(label);

    // Change #4: tidy things up a bit: subtract space for the 
    // control border, so the text stays inside the rectangle:
    text->Wrap(ev.GetSize().GetWidth()-50);
}

bool MyApp::OnInit()
{
    ClientFrame*
    frame = new ClientFrame("example", wxDefaultPosition, wxDefaultSize);
    frame->Show();
    return true;
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章