问题描述
我遇到了一个非常神秘的错误,这对我来说毫无意义。我在wxWidgets项目中使用CodeBlocks。在框架构造函数中,我创建了类fileManager的对象。然后,我调用一个fileManager方法,该方法将从GUI传递TextCtrl到fileManager进行存储,因此我将能够从fileManager中访问TextCtrl。 TextCtrl称为log_output。当我这样做时,我在fileManager中将一个指针设置为TextCtrl,称为local_log_output。然后,当我尝试调用其他fileManager方法并在该方法中使用该指针时,程序崩溃。
神秘的部分如下。如果这是我的框架构造函数:
MullSimple_3Frame::MullSimple_3Frame(wxFrame *frame,const wxString& title)
: wxFrame(frame,-1,title,wxPoint(0,0) )
{
iniGUI();
log_output->SetValue("HUH?");
FileManager fileManager;
fileManager.setlogoutput(log_output);
std::map<int,std::string> prog_vars_deck_pairs = fileManager.getMenuPairs( "deck","" );
}
程序正常运行,不会崩溃。 fileManager.getMenuPairs方法被称为Fine,它使用local_log_output。但是,如果我将对fileManager.getMenuPairs的调用移至框架中的单独函数,则按如下所示调用该函数:
MullSimple_3Frame::MullSimple_3Frame(wxFrame *frame,0) )
{
iniGUI();
log_output->SetValue("HUH?");
FileManager fileManager;
fileManager.setlogoutput(log_output);
testMethod();
}
void MullSimple_3Frame::testMethod()
{
std::map<int,"" );
}
程序在调用testMethod时崩溃,并且在我尝试设置local_log_output的值的getMenuPairs中的行上停止。
我唯一想到的可能是我在框架构造函数标头中声明变量/函数的顺序重要吗?在第一种情况下不会崩溃而在第二种情况下会崩溃的地方还有什么其他可能的区别?
这是框架的头文件
#ifndef MULLSIMPLE_2MAIN_H
#define MULLSIMPLE_2MAIN_H
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <vector>
#include "MullSimple_3App.h"
#include "non-wx/my_help_fxns.h"
#include "non-wx/file_manager.h"
#include "non-wx/data_vars.h"
#include "non-wx/simulator.h"
class MullSimple_3Frame: public wxFrame
{
public:
// constructor and destructor
MullSimple_3Frame(wxFrame *frame,const wxString& title);
~MullSimple_3Frame();
// logging output to terminal at bottom of gui
wxTextCtrl *log_output;
// reloads the deck load menu
void menuDeckOptsReload();
// just for trying to solve problem
void testMethod();
// VARIABLES
int unique_wx_id = 1000;
int curr_need_id = 0;
int last_active_need_row_id = -1;
std::vector<int> existing_needs_ids;
std::vector<wxBoxSizer*> existing_needs_sizers;
std::vector<need_layout_struct> existing_needs_items;
std::vector<std::vector<int>> existing_needs_widget_ids;
// WX GUI OBJECTS
wxPanel *main_panel;
wxMenu *deck_options_menu;
wxMenu *load_deck_sub_menu;
wxMenu *mull_options_menu;
wxMenu *mull_load_all_sub_menu;
wxMenu *mull_load_this_sub_menu;
wxStaticText *deck_info_id;
wxTextCtrl *deck_info_name;
wxTextCtrl *deck_info_set;
wxStaticText *deck_info_if_saved;
wxStaticText *mull_info_id;
wxTextCtrl *mull_info_name;
wxStaticText *mull_info_if_saved;
wxStaticText *deck_casts_title;
wxStaticText *deck_lands_title;
std::vector<wxTextCtrl*> deck_castable_inputs;
std::vector<wxButton*> deck_castable_info_buts;
std::vector<wxTextCtrl*> deck_land_inputs;
std::vector<wxButton*> deck_land_info_buts;
std::vector<wxTextCtrl*> hand_inputs;
wxButton *mull_opts_but_add_need;
wxButton *mull_opts_but_remove_need;
wxButton *mull_opts_but_reset_needs;
wxButton *mull_opts_but_simulate;
wxBoxSizer *needs_sizer_wrap;
// EVENT HANDLERS
void eMenuDeckOptsNew(wxCommandEvent &event);
void eMenuDeckOptsSave(wxCommandEvent &event);
void eMenuDeckOptsLoad(wxCommandEvent &event);
void eMenuMullOptsNew(wxCommandEvent &event);
void eMenuMullOptsSave(wxCommandEvent &event);
void eMenuMullOptsLoad(wxCommandEvent &event);
void eMenuHandOptsClear(wxCommandEvent &event);
// FUNCTIONS
void iniMenu();
void menuMullOptsReload();
void iniGUI();
void resetDeckInfo();
void resetDeckInputs();
void resetDeckInfoButs();
void resetHandInputs();
void resetMullInfo();
void resetMullInputs();
void deckCountCards();
bool deckCheckSaved();
void deckSortInputs(std::vector<std::string> deck_castable_strings,std::vector<std::string> deck_land_strings );
void deckUpdateInfoButs();
bool mullCheckSaved();
void mullAddNeed(int insert_after_count);
void mullNeedLineProcessRadiosAndChecks(need_layout_struct this_need_layout,std::string filter_class );
// CLASS REFERENCES
// file manager can save and load data
FileManager fileManager;
// data vars holds info about the cards in deck
DataVars dataVars;
// simulator sets up and runs sims
Simulator simulator;
private:
// we don't use the event table for handling events,instead we use
// connect for menu items and bind for controls,but still declare the table
DECLARE_EVENT_TABLE()
};
#endif // MULLSIMPLE_2MAIN_H
#ifndef FILE_MANAGER_H_INCLUDED
#define FILE_MANAGER_H_INCLUDED
#include <vector>
#include <map>
#include "prog_structs.h"
class FileManager
{
private:
public:
FileManager();
// pointer to the gui log_output
wxTextCtrl *local_log_output;
// passed log_output from gui,sets a pointer to it for access within this class
void setlogoutput(wxTextCtrl *log_output);
// gets id/name pairs for saved decks to populate menu items
std::map<int,std::string> getMenuPairs(
std::string type,// "deck" or "mull"
std::string deck_id // only needed for mull,if we want only mull data related to a specific deck
);
};
#endif // FILE_MANAGER_H_INCLUDED
#include <sstream>
#include <fstream>
#include <filesystem>
#include <map>
#include "file_manager.h"
#include "my_help_fxns.h"
FileManager::FileManager()
{
}
void FileManager::setlogoutput(wxTextCtrl *log_output)
{
local_log_output = log_output;
}
std::map<int,std::string> FileManager::getMenuPairs( std::string type,std::string deck_id )
{
// PROGRAM IS CRASHING HERE,WHY I DON"T KNow
local_log_output->SetValue("PRINTING B...");
std::map<int,std::string> menu_pairs;
return menu_pairs;
}
编辑:iniGUI()
// mainPanel
main_panel = new wxPanel(this,wxID_ANY);
// mainPanelSizer (vertical)
wxBoxSizer *main_panel_sizer = new wxBoxSizer(wxVERTICAL);
// info sizer
// deck info (id,name etc)
// mull info (id,name etc)
wxBoxSizer *info_sizer = new wxBoxSizer(wxHORIZONTAL);
main_panel_sizer->Add(info_sizer,wxSizerFlags(0).Expand());
// deckInfo (horizontal)
// deck data along top like deck name,deck id,deck set
wxBoxSizer *deck_info_sizer = new wxBoxSizer(wxHORIZONTAL);
info_sizer->Add(deck_info_sizer,wxSizerFlags(1).Expand());
// DECK ID
// label
wxStaticText *label1 = new wxStaticText(main_panel,wxID_ANY,"DECK ID: ");
deck_info_sizer->Add(label1,wxSizerFlags(0).Expand());
// value
deck_info_id = new wxStaticText(main_panel,"-1");
deck_info_sizer->Add(deck_info_id,wxSizerFlags(0).Expand());
// DECK NAME
// label
wxStaticText *label2 = new wxStaticText(main_panel,",NAME: ");
deck_info_sizer->Add(label2,wxSizerFlags(0).Expand());
// value
deck_info_name = new wxTextCtrl(main_panel,"");
deck_info_name->Bind(wxEVT_TEXT,&MullSimple_3Frame::eDeckInfoChangeValue,this);
deck_info_sizer->Add(deck_info_name,wxSizerFlags(0).Expand());
// DECK SET
// label
wxStaticText *label3 = new wxStaticText(main_panel,SET: ");
deck_info_sizer->Add(label3,wxSizerFlags(0).Expand());
// value
deck_info_set = new wxTextCtrl(main_panel,"");
deck_info_set->Bind(wxEVT_TEXT,this);
deck_info_set->Bind(wxEVT_KILL_FOCUS,&MullSimple_3Frame::eDeckInfoBlurSet,this);
deck_info_sizer->Add(deck_info_set,wxSizerFlags(0).Expand());
// DECK SAVED
// can't do stuff unless the deck is saved. saving allows us to set data_vars.
// label
wxStaticText *label4 = new wxStaticText(main_panel,SAVED: ");
deck_info_sizer->Add(label4,wxSizerFlags(0).Expand());
// value
deck_info_if_saved = new wxStaticText(main_panel,"FALSE");
deck_info_sizer->Add(deck_info_if_saved,wxSizerFlags(0).Expand());
wxBoxSizer *mull_info_sizer = new wxBoxSizer(wxHORIZONTAL);
info_sizer->Add(mull_info_sizer,wxSizerFlags(1).Expand());
// MULL ID
// label
wxStaticText *label5 = new wxStaticText(main_panel,"MULL ID: ");
mull_info_sizer->Add(label5,wxSizerFlags(0).Expand());
// value
mull_info_id = new wxStaticText(main_panel,"-1");
mull_info_sizer->Add(mull_info_id,wxSizerFlags(0).Expand());
// MULL NAME
// label
wxStaticText *label6 = new wxStaticText(main_panel,NAME: ");
mull_info_sizer->Add(label6,wxSizerFlags(0).Expand());
// value
mull_info_name = new wxTextCtrl(main_panel,"");
mull_info_name->Bind(wxEVT_TEXT,&MullSimple_3Frame::eMullInfoChangeValue,this);
mull_info_sizer->Add(mull_info_name,wxSizerFlags(0).Expand());
// MULL SAVED
// can't do stuff unless the deck is saved. saving allows us to set data_vars.
// label
wxStaticText *label7 = new wxStaticText(main_panel,SAVED: ");
mull_info_sizer->Add(label7,wxSizerFlags(0).Expand());
// value
mull_info_if_saved = new wxStaticText(main_panel,"FALSE");
mull_info_sizer->Add(mull_info_if_saved,wxSizerFlags(0).Expand());
// progSizer (horizontal)
// program contains 3 "columns"
wxBoxSizer *prog_sizer = new wxBoxSizer(wxHORIZONTAL);
main_panel_sizer->Add(prog_sizer,wxSizerFlags(1).Expand());
// PROGRAM COLUMN 1: DECK CASTABLES
// castables column
wxBoxSizer *deck_casts_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(deck_casts_sizer,wxSizerFlags(1).Expand());
// castables title
deck_casts_title = new wxStaticText(main_panel,"Castables (0)",wxDefaultPosition,wxSize(-1,30),wxALIGN_CENTER_HORIZONTAL|wxST_NO_AUTORESIZE);
deck_casts_title->SetBackgroundColour(*wxYELLOW);
deck_casts_sizer->Add(deck_casts_title,wxSizerFlags(0).Expand());
// castables content
// before we had just a single input arranged inside the sizer,but Now i think
// we want each row itself to be a sizer,with a button and an input
for ( int i = 0; i < 25; i++ )
{
wxBoxSizer *card_item_sizer = new wxBoxSizer(wxHORIZONTAL);
deck_casts_sizer->Add(card_item_sizer,wxSizerFlags(1).Expand());
// input
this->unique_wx_id++;
wxTextCtrl *card_input = new wxTextCtrl(main_panel,this->unique_wx_id,wxEmptyString,20));
//card_input->Bind(wxEVT_TEXT,&MullSimple_3Frame::GUIDeckCardsChangeValue,this);
//card_input->Bind(wxEVT_KILL_FOCUS,&MullSimple_3Frame::GUICardsChangeAutoComplete,this);
card_input->SetMinSize(wxSize(100,-1));
deck_castable_inputs.push_back(card_input);
card_item_sizer->Add(card_input,wxSizerFlags(1).Expand());
// button
this->unique_wx_id++;
wxButton *card_info_but = new wxButton(this->main_panel,"",wxSize(50,-1));
card_info_but->SetName("deck_cast_info_but_" + myHelpFxns::ToWxString(std::to_string(i + 1)));
//card_info_but->Bind(wxEVT_BUTTON,&MullSimple_3Frame::GUIDeckPrintCardInfo,this);
deck_castable_info_buts.push_back(card_info_but);
card_item_sizer->Add(card_info_but,wxSizerFlags(0).Expand());
}
// PROGRAM COLUMN 2: DECK LANDS
wxBoxSizer *deck_lands_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(deck_lands_sizer,wxSizerFlags(1).Expand());
// lands title
deck_lands_title = new wxStaticText(main_panel,"Lands (0)",wxALIGN_CENTER_HORIZONTAL|wxST_NO_AUTORESIZE);
deck_lands_title->SetBackgroundColour(*wxGREEN);
deck_lands_sizer->Add(deck_lands_title,wxSizerFlags(0).Expand());
// lands content
for ( int i = 0; i < 25; i++ )
{
wxBoxSizer *card_item_sizer = new wxBoxSizer(wxHORIZONTAL);
deck_lands_sizer->Add(card_item_sizer,20));
//card_input->Bind(wxEVT_TEXT,this);
card_input->SetMinSize(wxSize(100,-1));
deck_land_inputs.push_back(card_input);
card_item_sizer->Add(card_input,-1));
card_info_but->SetName("deck_land_info_but_" + myHelpFxns::ToWxString(std::to_string(i + 1)));
//card_info_but->Bind(wxEVT_BUTTON,this);
deck_land_info_buts.push_back(card_info_but);
card_item_sizer->Add(card_info_but,wxSizerFlags(0).Expand());
}
// PROGRAM COLUMN 3: HAND
wxBoxSizer *hand_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(hand_sizer,wxSizerFlags(1).Expand());
// hand title
wxStaticText *hand_title = new wxStaticText(main_panel,"Hand",wxALIGN_CENTER_HORIZONTAL);
hand_title->SetBackgroundColour(*wxBLUE);
hand_sizer->Add(hand_title,wxSizerFlags(0).Expand());
// hand content
for ( int i = 0; i < 7; i++ )
{
this->unique_wx_id++;
wxTextCtrl *text_ctrl = new wxTextCtrl(main_panel,20));
//text_ctrl->Bind(wxEVT_KILL_FOCUS,this);
text_ctrl->SetMinSize(wxSize(100,-1));
hand_inputs.push_back(text_ctrl);
hand_sizer->Add(text_ctrl,wxSizerFlags(0).Expand());
}
// PROGRAM COLUMN 4: MULL OPTS
// we'll set proportion 0 here and use the mull_opts_buttons to
// set a fixed width for the sizer
wxBoxSizer *mull_opts_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(mull_opts_sizer,wxSizerFlags(0).Expand());
// MULL OPTS HORIZONTAL 1: MULL_OPTS_BUTTONS
wxBoxSizer *mull_opts_but_sizer = new wxBoxSizer(wxHORIZONTAL);
mull_opts_sizer->Add(mull_opts_but_sizer,wxSizerFlags(0).Expand());
// add need button
mull_opts_but_add_need = new wxButton(main_panel,"+ Need");
mull_opts_but_add_need->SetMinSize(wxSize(200,50));
//mull_opts_but_add_need->Bind(wxEVT_BUTTON,&MullSimple_3Frame::globalNeedButAdd,this);
mull_opts_but_sizer->Add(mull_opts_but_add_need,wxSizerFlags(1).Expand());
// remove need button
mull_opts_but_remove_need = new wxButton(main_panel,"- Need");
mull_opts_but_remove_need->SetMinSize(wxSize(200,50));
//mull_opts_but_remove_need->Bind(wxEVT_BUTTON,&MullSimple_3Frame::globalNeedButRemove,this);
mull_opts_but_sizer->Add(mull_opts_but_remove_need,wxSizerFlags(1).Expand());
// reset all button
mull_opts_but_reset_needs = new wxButton(main_panel,"Reset All");
mull_opts_but_reset_needs->SetMinSize(wxSize(200,50));
//mull_opts_but_reset_needs->Bind(wxEVT_BUTTON,&MullSimple_3Frame::globalNeedButReset,this);
mull_opts_but_sizer->Add(mull_opts_but_reset_needs,wxSizerFlags(1).Expand());
// calculate button
mull_opts_but_simulate = new wxButton(main_panel,"Simulate");
mull_opts_but_simulate->SetMinSize(wxSize(200,50));
//mull_opts_but_simulate->Bind(wxEVT_BUTTON,&MullSimple_3Frame::globalNeedButSimulate,this);
mull_opts_but_sizer->Add(mull_opts_but_simulate,wxSizerFlags(1).Expand());
// needs sizer wrap,contains the needs,starts out empty
needs_sizer_wrap = new wxBoxSizer(wxVERTICAL);
mull_opts_sizer->Add(needs_sizer_wrap,wxSizerFlags(0).Expand());
// MULL OPTS HORIZONTAL 2: NEEDS (in a stack)
// Make on base need we can use as a model
// at the bottom of the main panel stretches the log output
// fixed height so set proportion 0
wxBoxSizer *output_sizer = new wxBoxSizer(wxHORIZONTAL);
main_panel_sizer ->Add(output_sizer,wxSizerFlags(0).Expand());
log_output = new wxTextCtrl(main_panel,200),wxTE_MULTILINE);
log_output->SetBackgroundColour(*wxYELLOW);
output_sizer ->Add(log_output,wxSizerFlags(1).Expand());
// TAB ORDER CHANGES
// tab order is annoying,no way to simply disable tabbing into an element.
// so for things i don't want to tab into easily,i use this to put them after the log_ouput
// which should be last in the panel
mull_info_name->MoveAfterInTabOrder(log_output); // mull info name input for the mull set
for ( unsigned int i = 0; i < deck_castable_info_buts.size(); i++ )
{
deck_castable_info_buts[i]->MoveAfterInTabOrder(log_output); // info buttons for each card (castables)
}
for ( unsigned int i = 0; i < deck_land_info_buts.size(); i++ )
{
deck_land_info_buts[i]->MoveAfterInTabOrder(log_output); // info buttons for each card (lands)
}
main_panel->SetSizerAndFit(main_panel_sizer);
this->Fit();
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)