WxWidgets 3.2.1中SetContainingWindow断言失败问题求助
问题描述
刚接触WxWidgets,程序在WxWidgets 3.1.5中运行正常,但升级到3.2.1后出现SetContainingWindow断言失败异常。查看3.2.1示例代码未发现自身代码问题,异常信息及源码如下:
异常信息
../src/common/sizer.cpp(887): assert "CheckExpectedParentIs(w, m_containingWindow)" failed in SetContainingWindow(): Windows managed by the sizer associated with the given window must have this window as parent, otherwise they will not be repositioned correctly. Please use the window wxNotebook@0x7f9a5d9547d0 ("notebook") with which this sizer is associated, as the parent when creating the window wxStaticText@0x7f9a5d957e40 ("SMART log for /dev/nvme0n1") managed by it. Collecting stack trace information, please wait...../src/common/sizer.cpp(887): assert "CheckExpectedParentIs(w, m_containingWindow)" failed in SetContainingWindow(): Windows managed by the sizer associated with the given window must have this window as parent, otherwise they will not be repositioned correctly. Please use the window wxNotebook@0x7f9a5d9547d0 ("notebook") with which this sizer is associated, as the parent when creating the window wxButton@0x7f9a5d9564e0 ("Copy to clilpboard") managed by it. Collecting stack trace information, please wait...../src/common/sizer.cpp(887): assert "CheckExpectedParentIs(w, m_containingWindow)" failed in SetContainingWindow(): Windows managed by the sizer associated with the given window must have this window as parent, otherwise they will not be repositioned correctly. Please use the window wxNotebook@0x7f9a5d9547d0 ("notebook") with which this sizer is associated, as the parent when creating the window wxGrid@0x7f9a5c892a00 ("grid") managed by it.
源码
int DlgDisplayLogs::insertPage(wxString caption, wxString hostname, wxArrayString strArray) { wxPanel* panel = new wxPanel(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize); wxButton* btnClipboard = new wxButton(panel, wxID_ANY, "Copy to clilpboard"); wxStaticText* label = new wxStaticText(panel, wxID_ANY, caption, wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE); wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL); hbox->Add(label, 1, wxEXPAND | wxRIGHT | wxBOTTOM, 10); hbox->Add(btnClipboard, 0, wxRIGHT | wxBOTTOM, 10); wxGrid* grid; int numEntries = strArray.GetCount(); grid = new wxGrid(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize); if (!grid) { return -1; } grid->CreateGrid(numEntries / 2, 2); grid->EnableEditing(false); grid->DisableCellEditControl(); grid->DisableDragGridSize(); grid->SetSelectionMode(wxGrid::wxGridSelectionModes::wxGridSelectRows); grid->SetColLabelValue(0, "Description"); grid->SetColLabelValue(1, "Value"); grid->SetColMinimalWidth(0, 250); grid->SetColMinimalWidth(1, 250); grid->SetColSize(0, 250); grid->SetColSize(1, 450); grid->SetCellHighlightPenWidth(0); grid->SetCellHighlightROPenWidth(0); wxBoxSizer* vbox = new wxBoxSizer(wxVERTICAL); // TODO hbox should be aligned to the right using wxALIGN_RIGHT vbox->Add(hbox, 0, wxLEFT | wxRIGHT | wxBOTTOM, 5); vbox->Add(grid, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); notebook->SetSizerAndFit(vbox); notebook->AddPage(panel, hostname, true); notebook->Layout(); //notebook->Refresh(); for (int row = 0, i = 0; i < numEntries; row++, i += 2) { grid->SetCellValue(row, 0, strArray[i]); grid->SetCellValue(row, 1, strArray[i + 1]); } return 0; }
问题分析与解决
核心错误:你把包含panel子控件的sizer(vbox)绑定给了notebook,但sizer内的按钮、文本、表格都是panel的子控件,并非notebook的子控件。WxWidgets 3.2.1加强了父子控件与sizer关联的校验,因此触发断言。
修正方案:
- 将
sizer绑定到对应的父控件panel,而非notebook - 调整逻辑顺序,确保控件的父子关系与sizer绑定匹配
修正后的关键代码片段:
// 替换原有的 notebook->SetSizerAndFit(vbox); panel->SetSizerAndFit(vbox); // 调整布局对象为panel notebook->AddPage(panel, hostname, true); panel->Layout();
完整修正后的函数:
int DlgDisplayLogs::insertPage(wxString caption, wxString hostname, wxArrayString strArray) { wxPanel* panel = new wxPanel(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize); wxButton* btnClipboard = new wxButton(panel, wxID_ANY, "Copy to clilpboard"); wxStaticText* label = new wxStaticText(panel, wxID_ANY, caption, wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE); wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL); hbox->Add(label, 1, wxEXPAND | wxRIGHT | wxBOTTOM, 10); hbox->Add(btnClipboard, 0, wxRIGHT | wxBOTTOM, 10); wxGrid* grid; int numEntries = strArray.GetCount(); grid = new wxGrid(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize); if (!grid) { return -1; } grid->CreateGrid(numEntries / 2, 2); grid->EnableEditing(false); grid->DisableCellEditControl(); grid->DisableDragGridSize(); grid->SetSelectionMode(wxGrid::wxGridSelectionModes::wxGridSelectRows); grid->SetColLabelValue(0, "Description"); grid->SetColLabelValue(1, "Value"); grid->SetColMinimalWidth(0, 250); grid->SetColMinimalWidth(1, 250); grid->SetColSize(0, 250); grid->SetColSize(1, 450); grid->SetCellHighlightPenWidth(0); grid->SetCellHighlightROPenWidth(0); wxBoxSizer* vbox = new wxBoxSizer(wxVERTICAL); // TODO hbox should be aligned to the right using wxALIGN_RIGHT vbox->Add(hbox, 0, wxLEFT | wxRIGHT | wxBOTTOM, 5); vbox->Add(grid, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); // 修正:将sizer绑定到panel而非notebook panel->SetSizerAndFit(vbox); notebook->AddPage(panel, hostname, true); // 对panel执行布局 panel->Layout(); //notebook->Refresh(); for (int row = 0, i = 0; i < numEntries; row++, i += 2) { grid->SetCellValue(row, 0, strArray[i]); grid->SetCellValue(row, 1, strArray[i + 1]); } return 0; }
修改后,sizer与控件的父子关系完全匹配,即可通过3.2.1的断言校验,同时保持原有功能正常。
内容的提问来源于stack exchange,提问作者Yogi Wannabe
相关产品推荐
相关产品推荐

