c++ - wxPropertyGrid 自定义 slider 属性问题

标签 c++ user-interface wxwidgets

我正在使用 wxWidgets 2.8,以及 wxPropertyGrid 1.4 在应用程序中。 对于浮点值,我想使用 slider 来编辑它们。但是,默认情况下不提供 slider 编辑器,因此我按照文档中提到的指南,采用了自己的编辑器。

但是,使用这个新编辑器,即使我将它设置为我的 float 属性的编辑器,它也不会真正出现,直到以任何方式与属性网格单元交互(例如单击)。在那之前,基于文本框的经典 Controller 仍然可见。

显然,当生成 propgrid 时,不会调用 slider 编辑器的实际 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 函数中用来生成 slider 的代码:

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);

我注册了这个类,以防它之前没有被注册过,然后设置属性的编辑器。然后我将属性添加到网格中。为什么在与单元格交互之前 slider 不显示?

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

最佳答案

你正在使用

#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);
}

关于c++ - wxPropertyGrid 自定义 slider 属性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12008306/

相关文章:

c++ - 默认初始化与从默认构造值复制初始化

c++ - 在 Singleton 设计模式的情况下,我们如何使析构函数私有(private)化?

c++ - 为什么尽管有一个 int vector ,但结构的大小不变

twitter-bootstrap - Bootstrap中div内的左对齐和右对齐

c++ - 安装 wxwidgets 2 时出现问题

python - wxGlade GUI行为问题

c++ - inotify_add_watch 失败,没有这样的文件或目录

c++ - 带空小部件的 Qt 拆分器

qt - 如何为图形 GUI 中显示的项目创建炫酷的 "mirror"效果?

c++ - 使用 wxWidgets 多线程时的奇怪行为