0

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

我的应用处于正常状态:

普通的

最大化应用:

最大化

当我将其最小化时:

最小化

wxTextCtrl我调整窗口大小时, 的大小最终会自行更新和纠正,但这个错误有点烦人。

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

text_controls.cpp

#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 很陌生。

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

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();
}

C2064在 VS2019 中出现错误:The term doesn't return a function that accepts 0 arguments.

编辑:

更改CallAfter(Layout());CallAfter(&Main::Layout);,我得到了同样的错误。

4

1 回答 1

1

让我改写你的描述:

“当我手动或通过最大化它来更改窗口的大小时,一切都很顺利。但是当我从最大化状态恢复窗口时,字体会错误地更新”

如果必须根据窗口大小相应地更改字体,则必须在控件中捕获大小事件。处理程序获取具有wxSizeEvent控件新大小的对象。
==>> 所以在你的lambdas中使用这个新的尺寸(即evt.GetSize()) 。control.GetSize()control->Bind(wxEVT_SIZE...)

问题来自 wxSizer 的布局过程使用控件中的当前字体来计算新大小的事实。因此,当您收到 size-event 时为时已晚,无法考虑新的 font-size。
因此,当再次调整窗口大小时,大小与上一个窗口的大小或多或少相同,那么旧字体大小与新字体大小相同,然后一切都匹配。

你能做什么?
捕获整个窗口的大小事件(仍然使用您的处理程序来更改字体)并在处理程序完成后调用“布局()”:

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

这第二个“布局”(第一个在 sizer 的代码中触发)可能会显示一些闪烁。

于 2021-07-11T19:26:27.680 回答