wxWidgets 3.1.5 MSW - HiDPI 缩放问题导致控件大小不正确
wxWidgets 3.1.5 MSW - HiDPI scaling problems causing controls to have the incorrect size
关于我的设置的信息
- wxWidgets:3.1.5(还尝试了来自 github 的最新源)
- wxWidgets:在 msys2 (ucrt64) 下使用 gcc-11.2 构建
- Windows 10 应用:在 msys2 (ucrt64) 下使用 gcc-11.2 构建
- 显示器原生分辨率:3840 x 2160
- IDE:日食 2021-09
我的问题
如果我构建我的应用程序并 link 针对未使用 HiDPI 感知清单的资源文件,则一切正常,但字体如预期的那样像素化。但是,一旦我 link 使用 HiDPI 感知资源文件,控件就不会与其关联的文本成比例地调整大小。请看以下截图。
上图显示了在没有 HiDPI 感知资源文件的情况下渲染的测试 wxFrame。监视器缩放比例为 200%。如您所见,wxFrame 已正确呈现。
上图显示了在没有 HiDPI 感知资源文件的情况下渲染的测试 wxFrame。显示器缩放比例为 350%。如您所见,(除了模糊的文本)wxFrame 已正确呈现..
上图显示了正在渲染的测试 wxFrame 和 一个 HiDPI 感知资源文件。监视器缩放比例为 200%。如您所见,wxFrame 渲染得很糟糕。此 wxFrame 以 100% 比例正确呈现。
这是一个最小的全功能代码示例来演示我的问题。
#include <wx/wx.h>
#include <wx/frame.h>
#include <wx/sizer.h>
#include <wx/button.h>
class HiDPI_Test: public wxFrame
{
public:
HiDPI_Test() :
wxFrame(NULL, wxID_ANY, "HiDPI Test")
{
wxBoxSizer *sizer_master = new wxBoxSizer(wxHORIZONTAL);
m_btn_1 = new wxButton(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_btn_1->SetMinSize(wxSize(-1, 30));
m_btn_1->SetMaxSize(wxSize(120, 30));
m_btn_1->SetLabel("Button Label Test");
m_btn_2 = new wxButton(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_btn_2->SetMinSize(wxSize(-1, 30));
m_btn_2->SetMaxSize(wxSize(120, 30));
m_btn_2->SetLabel("Button Label Test");
sizer_master->Add(m_btn_1, 0, wxALL | wxEXPAND, 0);
sizer_master->Add(m_btn_2, 0, wxALL | wxEXPAND, 0);
this->SetSizerAndFit(sizer_master);
this->Layout();
this->Centre(wxBOTH);
}
private:
wxButton *m_btn_1, *m_btn_2;
};
class HiDPI: public wxApp
{
public:
bool OnInit() override
{
HiDPI_Test *mainApp = new HiDPI_Test();
mainApp->Show();
return true;
}
};
wxIMPLEMENT_APP(HiDPI);
调用 SetMinSize() 和 SetMaxSize() 对我的整体 UI 设计至关重要。
我使用以下内容构建了 wxWidgets 资源文件:
windres --use-temp-file -ires.rc -ores.o -I/home/user/resource -DwxUSE_DPI_AWARE_MANIFEST=2
然后我在构建我的应用程序时将生成的目标文件传递给 linker。
重要的是要补充一点,我的应用程序可以在 wxWidgets/GTK3 (Linux) 和 wxWidgets macOS/Cocoa 上正确呈现。也就是说,它在 macOS 和 Linux 任何比例值下都能正常工作(没有像素化字体)。
有人知道为什么我在 Windows 10 上使用 HiDPI 感知资源文件时我的应用程序无法正确呈现吗?
通常使用像素大小是一个非常糟糕的主意,因为这没有考虑当前字体大小,因此使用 dialog units or just the result of GetTextExtent("something") 会更好。
但如果您绝对想使用像素,则至少需要使用 FromDIP()
将它们转换为正确的单位,请参阅 HiDPI overview in the manual 了解更多信息。
如果你使用
m_btn_1->SetMinSize(FromDIP(wxSize(-1, 30)));
m_btn_1->SetMaxSize(FromDIP(wxSize(120, 30)));
您的代码在 200% 缩放比例下按预期工作,至少对于当前的 master 是这样(我认为这也应该适用于 3.1.5,但是从那以后已经有大量 DPI-related 改进,因此,如果您关心高 DPI 支持,我强烈建议您使用即将发布的 master/3.1.6。
关于我的设置的信息
- wxWidgets:3.1.5(还尝试了来自 github 的最新源)
- wxWidgets:在 msys2 (ucrt64) 下使用 gcc-11.2 构建
- Windows 10 应用:在 msys2 (ucrt64) 下使用 gcc-11.2 构建
- 显示器原生分辨率:3840 x 2160
- IDE:日食 2021-09
我的问题
如果我构建我的应用程序并 link 针对未使用 HiDPI 感知清单的资源文件,则一切正常,但字体如预期的那样像素化。但是,一旦我 link 使用 HiDPI 感知资源文件,控件就不会与其关联的文本成比例地调整大小。请看以下截图。
上图显示了在没有 HiDPI 感知资源文件的情况下渲染的测试 wxFrame。监视器缩放比例为 200%。如您所见,wxFrame 已正确呈现。
上图显示了在没有 HiDPI 感知资源文件的情况下渲染的测试 wxFrame。显示器缩放比例为 350%。如您所见,(除了模糊的文本)wxFrame 已正确呈现..
上图显示了正在渲染的测试 wxFrame 和 一个 HiDPI 感知资源文件。监视器缩放比例为 200%。如您所见,wxFrame 渲染得很糟糕。此 wxFrame 以 100% 比例正确呈现。
这是一个最小的全功能代码示例来演示我的问题。
#include <wx/wx.h>
#include <wx/frame.h>
#include <wx/sizer.h>
#include <wx/button.h>
class HiDPI_Test: public wxFrame
{
public:
HiDPI_Test() :
wxFrame(NULL, wxID_ANY, "HiDPI Test")
{
wxBoxSizer *sizer_master = new wxBoxSizer(wxHORIZONTAL);
m_btn_1 = new wxButton(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_btn_1->SetMinSize(wxSize(-1, 30));
m_btn_1->SetMaxSize(wxSize(120, 30));
m_btn_1->SetLabel("Button Label Test");
m_btn_2 = new wxButton(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
m_btn_2->SetMinSize(wxSize(-1, 30));
m_btn_2->SetMaxSize(wxSize(120, 30));
m_btn_2->SetLabel("Button Label Test");
sizer_master->Add(m_btn_1, 0, wxALL | wxEXPAND, 0);
sizer_master->Add(m_btn_2, 0, wxALL | wxEXPAND, 0);
this->SetSizerAndFit(sizer_master);
this->Layout();
this->Centre(wxBOTH);
}
private:
wxButton *m_btn_1, *m_btn_2;
};
class HiDPI: public wxApp
{
public:
bool OnInit() override
{
HiDPI_Test *mainApp = new HiDPI_Test();
mainApp->Show();
return true;
}
};
wxIMPLEMENT_APP(HiDPI);
调用 SetMinSize() 和 SetMaxSize() 对我的整体 UI 设计至关重要。
我使用以下内容构建了 wxWidgets 资源文件:
windres --use-temp-file -ires.rc -ores.o -I/home/user/resource -DwxUSE_DPI_AWARE_MANIFEST=2
然后我在构建我的应用程序时将生成的目标文件传递给 linker。
重要的是要补充一点,我的应用程序可以在 wxWidgets/GTK3 (Linux) 和 wxWidgets macOS/Cocoa 上正确呈现。也就是说,它在 macOS 和 Linux 任何比例值下都能正常工作(没有像素化字体)。
有人知道为什么我在 Windows 10 上使用 HiDPI 感知资源文件时我的应用程序无法正确呈现吗?
通常使用像素大小是一个非常糟糕的主意,因为这没有考虑当前字体大小,因此使用 dialog units or just the result of GetTextExtent("something") 会更好。
但如果您绝对想使用像素,则至少需要使用 FromDIP()
将它们转换为正确的单位,请参阅 HiDPI overview in the manual 了解更多信息。
如果你使用
m_btn_1->SetMinSize(FromDIP(wxSize(-1, 30)));
m_btn_1->SetMaxSize(FromDIP(wxSize(120, 30)));
您的代码在 200% 缩放比例下按预期工作,至少对于当前的 master 是这样(我认为这也应该适用于 3.1.5,但是从那以后已经有大量 DPI-related 改进,因此,如果您关心高 DPI 支持,我强烈建议您使用即将发布的 master/3.1.6。