首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >wxTextCtrl调整大小问题

wxTextCtrl调整大小问题
EN

Stack Overflow用户
提问于 2021-07-10 08:05:16
回答 1查看 199关注 0票数 0

我正在创建一个wxWidgets C++计算器应用程序。我有一系列用于主表达式文本和其他内容的wxTextCtrl。当然,它们的位置使用的是size,这样当我调整窗口大小时,它们会变得更大或更小。然而,如果我最大化窗口,它们的大小就会成功地更新,但如果我将其最小化,则不会。

我的应用程序处于正常状态:

最大限度地应用:

当我把它减到最低限度时:

当我调整窗口的大小时,wxTextCtrl的大小最终会更新和更正,但是这个bug有点烦人。

下面是定义这些控件的代码:

text_controls.cpp

代码语言:javascript
复制
#include "main.h"

void Main::AddTextControls()
{
    auto sizer = new wxBoxSizer(wxVERTICAL);

    Chronology = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RIGHT);
    Chronology->SetBackgroundColour(wxColour(235, 235, 235));
    Chronology->SetForegroundColour(wxColour(105, 105, 105));
    Chronology->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
        evt.Skip();
        Chronology->SetFont(
            wxFontInfo(wxSize(0, Chronology->GetSize().y / 1.5))
            .Family(wxFONTFAMILY_SWISS)
            .FaceName("Calibri Light")
        );
    });
    sizer->Add(Chronology, 4, wxEXPAND);

    Expression = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RIGHT);
    Expression->SetForegroundColour(wxColour(55, 55, 55));
    Expression->Bind(wxEVT_TEXT, &Main::OnTextChange, this);
    Expression->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
        evt.Skip();
        Expression->SetFont(
            wxFontInfo(wxSize(0, Expression->GetSize().y / 1.3))
                .Family(wxFONTFAMILY_SWISS)
                .FaceName("Calibri")
                .Bold()
        );
    });
    sizer->Add(Expression, 10, wxEXPAND);

    //memoria
    auto memSizer = new wxBoxSizer(wxHORIZONTAL);

    MemText = new wxTextCtrl(this, wxID_ANY, "Memoria", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER);
    MemText->SetBackgroundColour(wxColour(55, 55, 55));
    MemText->SetForegroundColour(wxColour(119, 119, 119));
    MemText->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
        evt.Skip();
        MemText->SetFont(
            wxFontInfo(wxSize(0, MemText->GetSize().y / 1.3))
            .Family(wxFONTFAMILY_SWISS)
            .FaceName("Corbel")
        );
        });
    memSizer->Add(MemText, 25, wxEXPAND);

    Memory = new wxTextCtrl(this, wxID_ANY, "0", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxNO_BORDER | wxTE_RIGHT);
    Memory->SetBackgroundColour(wxColour(55, 55, 55));
    Memory->SetForegroundColour(wxColour(105, 105, 105));
    Memory->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
        evt.Skip();
        Memory->SetFont(
            wxFontInfo(wxSize(0, Memory->GetSize().y / 1.3))
            .Family(wxFONTFAMILY_SWISS)
            .FaceName("Calibri Light")
        );
        });
    memSizer->Add(Memory, 100, wxEXPAND);

    sizer->Add(memSizer, 3, wxEXPAND);

    MainSizer->Add(sizer, 30, wxEXPAND);
}

有人找到解决办法了吗?而且,我对wxWidgets非常陌生。

编辑:遵循一项建议,并将此片段添加到我的主框架构造函数中:

代码语言:javascript
复制
Main::Main() : wxFrame(nullptr, wxID_ANY, "IKE Calculator", wxDefaultPosition, wxSize(525, 650), wxDEFAULT_FRAME_STYLE)
{
    this->SetMinSize(wxSize(325, 450));

    FrameSize = this->GetSize();
    MainSizer = new wxBoxSizer(wxVERTICAL);

    this->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
        evt.Skip();
        CallAfter(Layout()); //will be called later
        });

    this->SetBackgroundColour(wxColour(70, 73, 101));

    AddTextControls();
    AddMainButtons();
    AddButtons();

    this->SetSizer(MainSizer);
    MainSizer->Layout();
}

在VS2019:The term doesn't return a function that accepts 0 arguments中获取一个VS2019错误。

编辑:

CallAfter(Layout());更改为CallAfter(&Main::Layout);,我将得到相同的错误。

EN

回答 1

Stack Overflow用户

发布于 2021-07-11 19:26:27

让我重述一下你的描述:

当我手动或最大化地改变窗口的大小时,一切都进行得很好。但是当我从最大化状态恢复窗口时,字体就会被错误地更新

如果字体必须随着窗口的大小相应更改,则大小事件必须在控件中捕获。处理程序获得一个具有控件新大小的wxSizeEvent对象。

因此,在您的==>> lambda中使用这个新的大小(即evt.GetSize())而不是control.GetSize()

这个问题来自于wxSizer的布局进程使用控件中的当前字体来计算新大小。因此,当您收到大小事件太晚,不能考虑新的字体大小。

因此,当窗口再次调整大小时,与前一个窗口大小大致相同,则旧字体大小与新字体大小相同,然后所有内容都匹配。

你能做什么?

捕获整个窗口的大小事件(仍然使用处理程序更改字体),并在处理程序完成后调用“Layout()”:

代码语言:javascript
复制
 MyFrame->Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
        evt.Skip();
        CallAfter(Layout()); //will be called later
        });

第二个'Layout`‘(第一个是在sizer的代码中触发的)可能会显示出一点闪烁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68325915

复制
相关文章

相似问题

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