Как и на предложенном примере, я реализовал ГУ с 2-мя кнопками. Обработчик событий Button1 (OnClick1) переключает значение логической переменной в верхнем классе wxFrame. Обработчик событий кнопки 2 (OnClick2) просто записывает значение такой переменной в журнал. Я вижу, что обработчики событий вызываются, как и ожидалось, но почему-то второй обработчик событий не видит изменений, внесенных обработчиком событий кнопки 1... Что-то идет не так. Кто-нибудь еще заметил странное поведение и может обнаружить проблему?
См. ниже код для воспроизведения наблюдаемого поведения
Код: Выделить всё
#include "stdafx.h"
#include "wx/wx.h"
#include
#include "wx/propgrid/propgrid.h"
class ButtonMover : public wxPGCellRenderer {
public:
// pointer to the button from the property
ButtonMover(wxButton* btn) : _btn(btn) {}
protected:
virtual bool Render(wxDC& dc, const wxRect& rect,
const wxPropertyGrid* propertyGrid, wxPGProperty* property,
int column, int item, int flags) const {
if (column == 0) { // 0 = label, 1 = value
// instead of actually drawing the cell,
// move the button to the cell position:
wxRect rc(rect);
// calculate the full property width
rc.SetWidth(propertyGrid->GetClientRect().width - rect.GetX());
_btn->SetSize(rc); // move button
_btn->Show(); // initially hidden, show once 'rendered' (moved)
}
return true;
}
private:
wxButton* _btn;
};
class ButtonProperty : public wxPGProperty {
public:
// [parent] should be the property grid
// [func] is the event handler
// [button] is the button label
// [label] is the property display name (sort name with autosort)
// [name] is the internal property name
ButtonProperty(wxWindow* parent, wxObjectEventFunction func,
const wxString& button, const wxString& label = wxPG_LABEL,
const wxString& name = wxPG_LABEL) :
wxPGProperty(label, name),
_btn(new wxButton(parent, wxID_ANY, button)),
_renderer(_btn)
{
// connect the handler to the button
_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, func);
_btn->Hide(); // when it's off the grid, it's not rendered
// (thus not moved properly)
}
protected:
virtual wxPGCellRenderer* GetCellRenderer(int column) const {
return &_renderer; // return button mover
}
virtual const wxPGEditor* DoGetEditorClass() const {
return 0; // not using an editor
}
private:
wxButton* _btn; // the button attached to the property
mutable ButtonMover _renderer; // the button mover //mutable
};
class MyApp : public wxApp
{
public:
virtual bool OnInit();
virtual int OnExit();
};
wxIMPLEMENT_APP(MyApp);
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent);
private:
void OnClick1(wxCommandEvent& evt);
void OnClick2(wxCommandEvent& evt);
bool mBool;
wxDECLARE_EVENT_TABLE();
};
int MyApp::OnExit()
{
return wxApp::OnExit();
}
bool MyApp::OnInit()
{
if (!wxApp::OnInit())
return false;
wxImage::AddHandler(new wxPNGHandler);
MyFrame* frame = new MyFrame(0L);
frame->Show(true);
return true;
}
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
wxEND_EVENT_TABLE()
MyFrame::MyFrame(wxWindow* parent):
wxFrame(parent, wxID_ANY, " Application"),
mBool(false)
{
wxPropertyGrid* lPG = new wxPropertyGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxPG_SPLITTER_AUTO_CENTER);
lPG->Append(new ButtonProperty(
lPG,
wxCommandEventHandler(MyFrame::OnClick1),
wxString("Click me!")));
lPG->Append(new ButtonProperty(
lPG,
wxCommandEventHandler(MyFrame::OnClick2),
"Edit this!")
);
// Layout stuff
lPG->SetMinSize(wxSize(300, 300));
wxBoxSizer* lGlobalVertSizer = new wxBoxSizer(wxVERTICAL);
lGlobalVertSizer->Add(lPG, 1, wxEXPAND | wxALL, 0);
SetSizerAndFit(lGlobalVertSizer);
// Open the log window and redirect messages to it
wxLogWindow* lLogWindow = new wxLogWindow(this, "Log Messages", false, false);
lLogWindow->GetFrame()->Move(GetPosition().x + GetSize().x + 10,GetPosition().y);
lLogWindow->Show();
}
void MyFrame::OnClick1(wxCommandEvent& evt)
{
mBool = !mBool;
wxLogMessage("OnClick1 mBool status: %s %llx", mBool ? "true": "false", (unsigned long long) & mBool);
}
void MyFrame::OnClick2(wxCommandEvent& evt)
{
wxLogMessage("OnClick2 mBool status: %s %llx", mBool ? "true": "false", (unsigned long long) & mBool);
}
OnClick1 и OnClick2 должны сообщать одно и то же значение mBool, поскольку переменная-член является то же самое....
отчеты wxLogMessage:
11:46:36: Состояние OnClick1 mBool: false 1ff29be5fa8
11:46:37: Состояние OnClick2 mBool false 1ff29c739b8
11:46:39: Состояние OnClick1 mBool: true 1ff29be5fa8
11:46:40: Состояние OnClick2 mBool false 1ff29c739b8
Подробнее здесь: https://stackoverflow.com/questions/783 ... sbehaviour