【问题标题】:wxTextCtrl resizing issuewxTextCtrl 调整大小问题
【发布时间】:2021-09-20 08:29:34
【问题描述】:

我正在创建一个 wxWidgets C++ 计算器应用程序。我有一系列wxTextCtrl 用于主要表达文本和其他内容。当然,它们是使用 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 很陌生。

编辑: 听从建议,将此 sn-p 添加到我的主框架构造函数中:

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 中出现 C2064 错误:The term doesn't return a function that accepts 0 arguments

编辑:

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

【问题讨论】:

    标签: c++ wxwidgets wxtextctrl sizer


    【解决方案1】:

    让我改写你的描述:

    “当我手动或最大化改变窗口大小时,一切正常。但是当我从最大化状态恢复窗口时,字体更新错误”

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

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

    你能做什么?
    捕捉整个窗口的 size 事件(仍然使用你的处理程序来改变字体)并在处理程序完成后调用 'Layout()':

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

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

    【讨论】:

    • 我尝试添加此代码,但出现错误(请参阅帖子,我已编辑)
    • @iKebab897 啊,是的。 CallAfter 应用作 CallAfter(&Main::Layout),其中“Main”是应用中框架的类。
    • 我试过但没有任何改变,请参阅帖子中的编辑
    猜你喜欢
    • 2011-07-05
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多