wxPropertyGrid自定义滑块属性问题

时间:2012-08-17 15:03:26

标签: c++ user-interface wxwidgets

我在应用程序中使用 wxWidgets 2.8和wxPropertyGrid 1.4 。 对于浮点值,我想使用滑块来编辑它们。但是,默认情况下不提供滑块编辑器,因此我按照文档中提到的准则使用了自己的编辑器。

然而,使用这个新编辑器,即使我将其设置为我的float属性的编辑器,它实际上并没有出现,直到属性网格单元以任何方式与之交互(例如,单击)。在此之前,经典的基于文本框的控制器仍然可见。

显然,当生成propgrid时,不会调用滑块编辑器的实际CreateControl方法 - 只有在单元格本身与某种方式进行交互时才会调用它。

这是我的自定义属性编辑器:

wxpgslider.h

class WXDLLIMPEXP_PG wxPGSliderEditor : public wxPGEditor 
{
#ifndef SWIG
  WX_PG_DECLARE_EDITOR_CLASS(wxPGSliderEditor)
#endif

public:
  wxPGSliderEditor (int p = 10000)
    : precision(p)
  {
  }

  ~wxPGSliderEditor ()
  {}

  // Macro for the CreateControls method stub
  wxPG_DECLARE_CREATECONTROLS

  void UpdateControl ( wxPGProperty* property, wxWindow* wnd) const;
  bool OnEvent ( wxPropertyGrid* propgrid, wxPGProperty* property, wxWindow* wnd, wxEvent& event) const;
  bool GetValueFromControl ( wxVariant& variant, wxPGProperty* property, wxWindow* wnd) const;
  void SetValueToUnspecified ( wxPGProperty* property, wxWindow* wnd) const;
  //void DrawValue ( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text) const;

private:
  int precision;
};

wxpgslider.cpp

#include "cseditor/wxpgslider.h"

//----------------- wxPGSliderEditor ---------------------

WX_PG_IMPLEMENT_EDITOR_CLASS(SliderEditor, wxPGSliderEditor, wxPGEditor)

wxPGWindowList wxPGSliderEditor::CreateControls( wxPropertyGrid*  propgrid,
                                                 wxPGProperty*    property,
                                                 const wxPoint&   pos,
                                                 const wxSize&    size ) const
{
  double v_d = property->GetValue().GetDouble();
  if ( v_d  1 )
    v_d = 1;

  wxSlider *ctrl = new wxSlider();

#ifdef __WXMSW__
  ctrl->Hide();
#endif

  ctrl->Create ( propgrid->GetPanel(),
                 wxPG_SUBID2,
                 (int)(v_d * precision),
                 0,
                 precision,
                 pos,
                 size,
                 wxSL_HORIZONTAL );

  return wxPGWindowList(ctrl);
}

void wxPGSliderEditor::UpdateControl ( wxPGProperty* property, wxWindow* wnd ) const
{
  wxSlider* ctrl = wxDynamicCast ( wnd, wxSlider );
  if ( ctrl )
  {
    double val;
    if (wxPGVariantToDouble (property->DoGetValue(), &val))
    {
      if ( val  1 )
        val = 1;
      ctrl->SetValue ( (int)(val * precision) );

      //static_cast(property)->GetLabel()
      //  ->SetValue( wxString::Format(wxT("%ld"), val * precision) );
    }
  }
}

bool wxPGSliderEditor::OnEvent ( wxPropertyGrid*  propgrid, 
                                 wxPGProperty*    property,
                                 wxWindow*        wnd,
                                 wxEvent&         event ) const
{
  if(event.GetEventType() == wxEVT_SCROLL_CHANGED)
  {
    // Update the value    
    event.Skip();
    propgrid->EditorsValueWasModified();

    return true;
  }

  return false;
}

bool wxPGSliderEditor::GetValueFromControl ( wxVariant&     variant,
                                             wxPGProperty*  property,
                                             wxWindow*      wnd ) const
{
  wxSlider* ctrl = wxDynamicCast ( wnd, wxSlider );
  if ( ctrl )
  {
    variant = wxVariant ( (double)(ctrl->GetValue())/(double)(precision) );
    property->SetValue ( variant );
  }

  return true;
}

void wxPGSliderEditor::SetValueToUnspecified ( wxPGProperty* property, wxWindow* wnd) const
{
  wxSlider* ctrl = wxDynamicCast ( wnd, wxSlider );
  if ( ctrl )
  {
    ctrl->SetValue (0);
  }
}

这是我在Populate函数中用来生成滑块的代码:

double value = variant->GetFloat();

// Generate a homebrewed slider
wxFloatProperty* fp = new wxFloatProperty(translatedName, originalName, value);
wxPGEditor* rHandle = wxPropertyGrid::RegisterEditorClass(new wxPGSliderEditor(), wxT("SliderEditor"));
fp->SetEditor(rHandle);
page->AppendIn(categoryID, fp);

我注册了这个类,如果以前没有注册过,那么设置属性的编辑器。然后我将属性添加到网格中。为什么滑块在单元格与?

交互之前不会显示

调用pgMan->GetGrid()->SelectProperty(fp, false);是让它被绘制的唯一方法吗?

1 个答案:

答案 0 :(得分:0)

您正在使用

#ifdef __WXMSW__
  ctrl->Hide();
#endif

是什么关于

#ifdef __WXMSW__
    ctrl->Show();
#endif

样品:

....
  wxSlider* ctrl = new wxSlider();
#ifdef __WXMSW__
    ctrl->Hide();
#endif
....
ctrl->Create ( propgrid->GetPanel(),
             wxPG_SUBID2,
             (int)(v_d * precision),
             0,
             precision,
             pos,
             size,
             wxSL_HORIZONTAL );

#ifdef __WXMSW__
    ctrl->Show();
#endif

return wxPGWindowList(ctrl);
}

修改

我在代码中看不到OnCustomEditorEvent。

使用wxEVT_SCROLL_THUMBTRACK或wxEVT_SCROLL_CHANGED。

....

propgrid->Connect( wxPG_SUBID2, wxEVT_SCROLL_CHANGED,
                       (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
                       &wxPropertyGrid::OnCustomEditorEvent, NULL, propgrid );

#ifdef __WXMSW__
  ctrl->Show();
#endif

return wxPGWindowList(ctrl);
}