【问题标题】:Is this possible with wxWidgets?wxWidgets可以做到这一点吗?
【发布时间】:2016-10-19 03:56:09
【问题描述】:

上周我一直在学习 wxWidgets,包括使用 IDE 和编写 C++ 代码。我开始对获得看起来不错的东西感到绝望,因为放置物品的能力似乎非常有限。

出于成本原因,我正在将一个大型项目从 C++Builder 移植到 VStudio。我有很多对话框要重新创建。它们通常包含输入“块”的不同组合——因为没有更好的词。我为我的 GUI 选择了 wxWidgets,因为我认为我可以通过生成一行表单的函数在代码中构建对话框。例如,在下面显示的对话框中,我可能具有 CreateLabelEdit、CreateLabelCombo、CreateBoldLabel 等函数。实际上,我在该部分取得了一些成功,但在设置对话框样式时却惨遭失败。

以下是这种特殊形式的一些设计标准:

  1. 所有输入都是左对齐的,并且不同的宽度适合其内容。

  2. 输入标签全部右对齐。

  3. 对齐点(即包含输入标签的列的宽度在所有对话框中都是相同的,各种输入的宽度也是如此。当然也有例外!

  4. 其他类型的标签在不同的位置对齐。在这种情况下加粗标签。

基本上我想控制我的对象的大小、位置和对齐方式。 这是否是我选择工具的心态错误?或者这些类型的事情可以用这个工具完成吗?


部分解决方案 我尝试过将绝对位置与 sizers 混合使用,但这根本不起作用。

然后我尝试使用 flexgrid sizer 来完成示例的一部分,如果我可以制作其中一个块,那么我可以将多个块拼接在一起。一切都很好,除非我使用 SetItemMinSize 设置第一列的宽度,正如@VZ 建议的那样,该项目失去了它的 sizerflag 设置:

form4::form4() :wxDialog(nullptr, wxID_ANY, "title")
{
    wxSizerFlags flagT1(1);
    flagT1.Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT).Border(wxTOP | wxLEFT, 10);
    wxSizerFlags flagT2(1);
    flagT2.Align(wxALIGN_CENTER_VERTICAL ).Border(wxTOP | wxLEFT, 10);
    wxSizerFlags flagT3(1);
    flagT3.Align(wxALIGN_CENTER_VERTICAL).Border(wxTOP | wxLEFT| wxRIGHT, 10);

    wxBoxSizer* bSize = new wxBoxSizer(wxVERTICAL);
    wxStaticText* _Text = new wxStaticText(this, wxID_ANY, "this should be bold");
    wxFont _Font = _Text->GetFont();
    _Font.MakeBold();
    _Font.SetPixelSize(_Font.GetPixelSize()*1.1);
    _Text->SetFont(_Font);
    bSize->Add(_Text, wxSizerFlags().Border(wxTOP, 10).Center());
    bSize->Add(new wxStaticText(this, wxID_ANY, "this should be bold"), 

    wxSizerFlags().Border(wxTOP, 10).Center());
    wxFlexGridSizer* bSizer = new wxFlexGridSizer(3,0,0);
    _Text = new wxStaticText(this, wxID_ANY, "bob");
    // bSizer->SetItemMinSize(_Text, wxSize(150, -1)); //this has no effect here
    bSizer->Add(_Text, flagT1);
    bSizer->SetItemMinSize(_Text, wxSize(150, -1));// loses styling of flagT1
    bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value", wxDefaultPosition, wxSize(150, -1)), flagT2);
    bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);

    bSizer->Add(new wxStaticText(this, wxID_ANY, " longer"), flagT1);
    bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value2", wxPoint(-1, -1), wxSize(150, -1)), flagT2);
    bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);

    bSizer->Add(new wxStaticText(this, wxID_ANY, "bob"), flagT1);
    bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value3", wxPoint(-1, -1), wxSize(150, -1)), flagT2);
    bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);

    bSize->Add(bSizer);

    bSize->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags(0).Border(wxALL, 10));
    this->SetSizerAndFit(bSize);
    //  this->Layout();
    this->Centre(wxBOTH);
}

产生这个:

【问题讨论】:

  • 你是做绝对定位还是使用sizer布局?
  • 试试 wxFormBuilder
  • @smcd,我一直在尝试使用 sizers,因为所有文档都建议这样做,但现在我认为为 x 组件提供大小并让 sizer 处理 y 组件可能是解决方案。
  • 如果你愿意使用 CodeLite IDE,这里有 wxCrafter。

标签: wxwidgets


【解决方案1】:

这个特殊的对话框并不是特别简单地在 wxWidgets 中创建,因为它不能用简单的wxFlexGridSizer 来完成。您有多种选择:

  1. 如果您愿意稍微妥协,请将粗体标签完全移到左栏中。然后它变成了一个简单的两列wxFlexGridSizer,在代码或对话框编辑器中创建它应该非常容易。
  2. 如果您想精确地保留此布局但仍想使用wxFlexGridSizer,您需要拥有其中的几个并手动对齐它们的第一列。方法是找到最长标签的宽度(使用GetTextExtent()),并为所有sizer设置最小项目大小(SetItemMinSize())。
  3. 如果您不想费心计算宽度,但仍想拥有这种精确的布局,您也可以使用wxGridBagSizer。就个人而言,我不建议使用它,因为它比较麻烦(您必须手动跟踪列/行),但它确实可以让您完全按照自己的意愿行事。

【讨论】:

  • 您能否提供一个如何使用 SetItemMinSize 的示例?我已经修改了我的问题并尝试使用它,但它有副作用..
  • 如果你的标签占用的空间比它需要的多,你需要右对齐它里面的文本,让它按照你的需要有效对齐,即使用wxALIGN_RIGHT作为wxStaticText的样式。
  • 这正是我在代码示例中所做的事情 flagT1 有wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT。如果我在添加到 sizer 之前将 setminsize 应用于 statictext 控件,那么 sizerflag 会覆盖它并且我没有得到 minsize,但是如果我将它添加到带有标志的 sizer 然后应用 minsize 我得到没有样式的大小.
  • 不,正如我所写,您需要使用wxALIGN_RIGHT 作为 wxStaticText 本身的样式,而不是包含它的 sizer 项目的样式。确保您了解这里发生了什么,以及如果您明确设置其最小尺寸,为什么 sizer 项目的对齐是无关紧要的。
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多