我有一个使用 wxMathplot 库创建的绘图,在最初的午餐时,该绘图工作完美,但是当我调整窗口大小时,它卡住了,笔记本电脑冻结,直到我重新启动它,在冻结之前,我注意到消耗 RAM 线性增加直到饱和,某种内存泄漏,当我注释掉 mpWindow 及其相关组件时,一切正常,这是我的代码的一部分
#include <wx/wx.h>
#include "wxmathplot/mathplot.h"
class PlotUI : public wxPanel
{
public:
PlotUI(wxWindow* parent, int ID);
void setTopPlot();
void setBottomLeftPlot();
void setBottomRightPlot();
void OnRefreshTopPlot(wxCommandEvent& evt);
void OnSaveTopPlot(wxCommandEvent& evt);
void OnRefreshBottomLeftPlot(wxCommandEvent& evt);
void OnSaveBottomLeftPlot(wxCommandEvent& evt);
void OnRefreshBottomRightPlot(wxCommandEvent& evt);
void OnSaveBottomRightPlot(wxCommandEvent& evt);
public:
wxBoxSizer* mainSizer;
wxBoxSizer* topSizer;
wxBoxSizer* bottomSizer;
wxStaticBox* topPlot;
wxBoxSizer* topPlotSizer;
wxBoxSizer* topPlotSizer_plot;
wxBoxSizer* topPlotSizer_control;
wxStaticBox* topPlotSB_control;
wxStaticBox* topPlotSB_plot;
wxCheckBox* T_1_checkBox;
wxCheckBox* T_2_checkBox;
wxCheckBox* T_3_checkBox;
wxButton* refreshTopPlot;
wxButton* saveTopPlot;
mpWindow* topPlot_plot;
};
PlotUI::PlotUI(wxWindow* parent, int ID) : wxPanel(parent, ID)
{
SetBackgroundColour(ztcColorCred);
mainSizer = new wxBoxSizer(wxVERTICAL);
topSizer = new wxBoxSizer(wxHORIZONTAL);
bottomSizer = new wxBoxSizer(wxHORIZONTAL);
topPlot = new wxStaticBox(this, -1,"");
setTopPlot();
topSizer->Add(topPlot, 1, wx1AND | wxALL, 5);
mainSizer->Add(topSizer, 1, wx1AND);
SetSizer(mainSizer);
}
void PlotUI::setTopPlot()
{
topPlotSizer = new wxBoxSizer(wxHORIZONTAL);
topPlotSizer_control = new wxBoxSizer(wxVERTICAL);
topPlotSizer_plot = new wxBoxSizer(wxVERTICAL);
topPlotSB_control = new wxStaticBox(topPlot, -1, "",wxDefaultPosition,wxSize(100,-1));
topPlotSizer_control->AddStretchSpacer(1);
T_1_checkBox = new wxCheckBox(topPlotSB_control, -1,"T_1");
topPlotSizer_control->Add(T_1_checkBox, 0, wx1AND | wxALL, 10);
T_2_checkBox_checkBox = new wxCheckBox(topPlotSB_control, -1, "T_2");
topPlotSizer_control->Add(T_2_checkBox_checkBox, 0, wx1AND | wxALL, 10);
T_s_checkBox = new wxCheckBox(topPlotSB_control, -1, "T_3");
topPlotSizer_control->Add(T_s_checkBox, 0, wx1AND | wxALL, 10);
refreshTopPlot = new wxButton(topPlotSB_control,-1,"Refresh");
refreshTopPlot->Bind(wxEVT_BUTTON, &PlotUI::OnRefreshTopPlot,this);
topPlotSizer_control->Add(refreshTopPlot, 0, wx1AND | wxALL, 10);
saveTopPlot = new wxButton(topPlotSB_control, -1, "Save");
saveTopPlot->Bind(wxEVT_BUTTON, &PlotUI::OnSaveTopPlot,this);
topPlotSizer_control->Add(saveTopPlot, 0, wx1AND | wxALL, 10);
topPlotSizer_control->AddStretchSpacer(1);
topPlotSB_control->SetSizer(topPlotSizer_control);
topPlotSizer->Add(topPlotSB_control, 0, wx1AND | wxALL, 10);
topPlotSB_plot = new wxStaticBox(topPlot, -1, "");
topPlot_plot = new mpWindow(topPlotSB_plot, -1);
topPlotSizer_plot->Add(topPlot_plot, 1, wx1AND);
topPlotSB_plot->SetSizer(topPlotSizer_plot);
topPlotSizer->Add(topPlotSB_plot, 1, wx1AND | wxALL, 10);
topPlot->SetSizer(topPlotSizer);
}
void PlotUI::OnRefreshTopPlot(wxCommandEvent& evt)
{
AppData& appData = AppData::getInstance();
std::vector<double>& x = userData.xData;
std::vector<double>& T_1 = userData.yData;
std::vector<double>& T_2_checkBox = userData.fitTdata;
std::vector<double>& T_3 = userData.fitTSdata;
if (T_1_checkBox->IsChecked() && T_2_checkBox_checkBox->IsChecked() && T_3_checkBox->IsChecked())
{
wxMessageBox("top 111");
if((topPlot_plot->CountAllLayers())>0) topPlot_plot->DelAllLayers(false, true);
topPlot_plot->SetMargins(30, 30, 40, 60);
topPlot_plot->SetBackgroundColour(ztcColorCred);
mpScaleX* xAxis = new mpScaleX("Wavelength (nm)", mpALIGN_BOTTOM, false, mpX_NORMAL);
mpScaleY* yAxis = new mpScaleY("Transmittance (AU)", mpALIGN_LEFT, false);
xAxis->SetDrawOutsideMargins(false);
yAxis->SetDrawOutsideMargins(false);
topPlot_plot->AddLayer(xAxis);
topPlot_plot->AddLayer(yAxis);
mpFXYVector* T_1_Layer = new mpFXYVector("T_1");
T_1_Layer->SetData(x, T_1);
T_1_Layer->SetPen(wxPen(*wxRED, 3, wxPENSTYLE_SOLID));
mpFXYVector* T_2_checkBox_Layer = new mpFXYVector("T_2");
T_2_checkBox_Layer->SetData(x, T_2_checkBox);
T_2_checkBox_Layer->SetPen(wxPen(*wxBLUE, 3, wxPENSTYLE_SOLID));
mpFXYVector* T_s_Layer = new mpFXYVector("T_3");
T_s_Layer->SetData(x, T_3);
T_s_Layer->SetPen(wxPen(*wxGREEN, 3, wxPENSTYLE_SOLID));
topPlot_plot->AddLayer(T_1_Layer);
topPlot_plot->AddLayer(T_2_checkBox_Layer);
topPlot_plot->AddLayer(T_s_Layer);
topPlot_plot->Fit(0.0,5000.0,0.0,1.0);
topPlot_plot->UpdateAll();
topPlotSizer_plot->Layout();
}
}
我之前使用过这个库没有问题
我尝试将绘图放在单独的类中,并跳过调整大小事件,我在 VS2022 中进行了一些调试。
我注意到问题出在调试模式下 wxwidgets 的事件处理机制(这是我的想法,我不是 wxwidgets 专家),我切换到发布模式来测试我的想法,每件事都使用相同的代码完美运行。这为我解决了这个问题,我不会接受我的最终答案,看看wxwidgest的专家是否会提出更好的解决方案。