📄 pg_dox_mainpage.h
字号:
#include <wx/propgrid/advprops.h>
...
// wxArrayStringProperty embeds a wxArrayString.
pg->Append ( wxArrayStringProperty(wxT("Example of ArrayStringProperty"),
wxT("ArrayStringProp")));
// Image file property. Wildcard is auto-generated from available
// image handlers, so it is not set this time.
pg->Append ( wxImageFileProperty(wxT("Example of ImageFileProperty"),
wxT("ImageFileProp")));
// Font property has sub-properties. Note that we give window's font as
// initial value.
pg->Append ( wxFontProperty(wxT("Font"),
wxPG_LABEL,
GetFont()) );
// Colour property with arbitrary colour.
pg->Append ( wxColourProperty(wxT("My Colour 1"),
wxPG_LABEL,
wxColour(242,109,0) ) );
// System colour property.
pg->Append ( wxSystemColourProperty (wxT("My SysColour 1"),
wxPG_LABEL,
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) );
// System colour property with custom colour.
pg->Append ( wxSystemColourProperty (wxT("My SysColour 2"),
wxPG_LABEL,
wxColour(0,200,160) ) );
// Cursor property
pg->Append ( wxCursorProperty (wxT("My Cursor"),
wxPG_LABEL,
wxCURSOR_ARROW));
\endcode
\section operations Operating with Properties
All operations on properties should be done via wxPropertyGrid's
(or wxPropertyGridManager's) methods. Class reference of the base property
class should only be interesting for those creating custom property classes.
Property operations, such as SetPropertyValue or DisableProperty,
all have two versions: one which accepts property id (of type wxPGId) and
another that accepts property name. Id is faster since it doesn't require
hash map lookup, but name is often much more convenient.
You can get property id as Append/Insert return value, or by calling
GetPropertyByName.
Example: Setting things about property named "X":
\code
// Altough name usually works, id is used here as an example
wxPGId id = GetPropertyByName(wxT("X"));
// There are many versions of this method, of which each accept
// different type of value.
// NOTE: If type of X is not "long", then this will yield a
// run-time error message.
pg->SetPropertyValue ( wxT("X"), 200 );
// Setting a string works for all properties - conversion is done
// automatically.
pg->SetPropertyValue ( id, wxT("400") );
// Set new name.
pg->SetPropertyName ( wxT("X"), wxT("NewNameOfX") );
// Set new label - we need to use the new name.
pg->SetPropertyLabel ( wxT("NewNameOfX"), wxT("New Label of X") );
\endcode
Example of iterating through all properties (that are not category or
sub-property items):
\code
wxPGId id = pg->GetFirstProperty();
while ( id.IsOk() )
{
// Do something with property id
...
// Get next
pg->GetNextProperty( id );
}
\endcode
Getting value of selected wxSystemColourProperty (which value type is derived
from wxObject):
\code
wxPGId id = pg->GetSelection();
if ( id.IsOk() )
{
// Get name of property
const wxString& name = pg->GetPropertyName ( id );
// If type is not correct, GetColour() method will produce run-time error
if ( pg->IsPropertyValueType ( id, CLASSINFO(wxColourPropertyValue) ) )
{
wxColourPropertyValue* pcolval =
wxDynamicCast(pg->GetPropertyValueAsWxObjectPtr(id),
wxColourPropertyValue);
// Report value
wxString text;
if ( pcolval->m_type == wxPG_CUSTOM_COLOUR )
text.Printf ( wxT("It is custom colour: (%i,%i,%i)"),
(int)pcolval->m_colour.Red(),
(int)pcolval->m_colour.Green(),
(int)pcolval->m_colour.Blue());
else
text.Printf ( wxT("It is wx system colour (number=%i): (%i,%i,%i)"),
(int)pcolval->m_type,
(int)pcolval->m_colour.Red(),
(int)pcolval->m_colour.Green(),
(int)pcolval->m_colour.Blue());
wxMessageBox ( text );
}
}
\endcode
\section populating Populating wxPropertyGrid Automatically
\subsection fromvariants Populating from List of wxVariants
Example of populating an empty wxPropertyGrid from a values stored
in an arbitrary list of wxVariants.
\code
// This is a static method that initializes *all* builtin type handlers
// available, including those for wxColour and wxFont. Refers to *all*
// included properties, so when compiling with static library, this
// method may increase the executable size significantly.
pg->InitAllTypeHandlers ();
// Get contents of the grid as a wxVariant list
wxVariant all_values = pg->GetPropertyValues();
// Populate the list with values. If a property with appropriate
// name is not found, it is created according to the type of variant.
pg->SetPropertyValues ( my_list_variant );
// In order to get wxObject ptr from a variant value,
// wxGetVariantCast(VARIANT,CLASSNAME) macro has to be called.
// Like this:
wxVariant v_txcol = pg->GetPropertyValue(wxT("Text Colour"));
const wxColour& txcol = wxGetVariantCast(v_txcol,wxColour);
\endcode
\subsection tofile Saving Population to a Text-based Storage
\code
static void WritePropertiesToMyStorage( wxPropertyGrid* pg, wxPGId id, wxMyStorage& f, int depth )
{
wxString s;
wxString s2;
while ( id.IsOk() )
{
// TODO: Save property into text storage using:
// wxPropertyGrid::GetPropertyClassName
// wxPropertyGrid::GetPropertyName
// wxPropertyGrid::GetPropertyLabel
// wxPropertyGrid::GetPropertyValueAsString
// wxPropertyGrid::GetPropertyChoices
// wxPropertyGrid::GetPropertyAttributes
// Example for adding choices:
wxPGConstants& choices = pg->GetPropertyChoices(id);
if ( choices.GetCount() )
{
// First add id of the choices list inorder to optimize
s2.Printf(wxT("\"%X\""),(unsigned int)choices.GetId());
s.Append(s2);
f.AddToken(s2);
size_t i;
wxArrayString& labels = choices.GetLabels();
wxArrayInt& values = choices.GetValues();
if ( values.GetCount() )
for ( i=0; i<labels.GetCount(); i++ )
{
s2.Printf(wxT("\"%s||%i\""),labels[i].c_str(),values[i]);
f.AddToken(s2);
}
else
for ( i=0; i<labels.GetCount(); i++ )
{
s2.Printf(wxT("\"%s\""),labels[i].c_str());
f.AddToken(s2);
}
}
// Write children, if any
wxPGId firstChild = pg->GetFirstChild(id);
if ( firstChild.IsOk() )
{
WritePropertiesToMyStorage( pg, firstChild, f, depth+1 );
// TODO: Add parent's terminator
}
id = pg->GetNextSibling(id);
}
}
...
// Then you can use this to store the entire hierarchy
wxPGId firstChild = pg->GetFirstChild(pg->GetRoot());
if ( firstChild.IsOk() )
WritePropertiesToFile(pg,first_child,InstanceOfMyStorage,0);
\endcode
For more practical'ish example, see FormMain::OnSaveToFileClick in
propgridsample.cpp.
\subsection fromfile Loading Population from a Text-based Storage
\code
// Recommended when modifying the grid a lot at once
pg->Freeze();
// Necessary if you want a full-page loading
pg->Clear();
wxPropertyGridPopulator populator(pg);
// Store strings from the source here
wxString s_class;
wxString s_name;
wxString s_value;
wxString s_attr;
// Each set of choices loaded must have id
size_t choicesId;
wxArrayString choiceLabels;
wxArrayInt choiceValues;
// Pseudo-code loop to parse the source one "line" at a time
while ( !source.IsAtEnd() )
{
// Clear stuff that doesn't exist at every "line"
choicesId = 0;
choiceLabels.Empty();
choiceValues.Empty();
// TODO: Load "line" to variables
// TODO: When a sequence of sibling properties is terminated, call this:
// populator.EndChildren();
// TODO: If had choices, use following code:
// if ( choicesId && !populator.HasChoices(choicesId) )
// {
// populator.AddChoices(choicesId,choiceLabels,choiceValues);
// }
// TODO: Add the property.
// (for sake of simplicity we use here default name for properties)
// populator.AppendByClass(s_class,
// s_name,
// wxPG_LABEL,
// s_value,
// s_attr,
// choicesId);
// TODO: When a sequence of sibling properties begins, call this:
// populator.BeginChildren();
}
pg->Thaw();
\endcode
For more practical'ish example, see FormMain::OnLoadFromFileClick in
propgridsample.cpp.
\section events Event Handling
Probably the most important event is the Changed event which occurs when
value of any property is changed by the user. Use EVT_PG_CHANGED(id,func)
in your event table to use it.
For complete list of event types, see wxPropertyGrid class reference.
The custom event class, wxPropertyGridEvent, has methods to directly
access the property that triggered the event.
Here's a small sample:
\code
// Portion of an imaginary event table
BEGIN_EVENT_TABLE(MyForm, wxFrame)
...
// This occurs when a property value changes
EVT_PG_CHANGED( PGID, MyForm::OnPropertyGridChange )
...
END_EVENT_TABLE()
void MyForm::OnPropertyGridChange ( wxPropertyGridEvent& event )
{
// Get name of changed property
const wxString& name = event.GetPropertyName();
// Get resulting value - wxVariant is convenient here.
wxVariant value = event.GetPropertyValue();
// Get type identifier
const wxPGValueType* type = event.GetPropertyValueType();
}
\endcode
\section custprop Custom User Properties (using wxCustomProperty)
By far the easiest way to have a somewhat customized property
is to use wxCustomProperty class. No subclassing is necessary -
property is modified using wxPropertyGrid::SetPropertyAttribute.
<b>Available Customizations</b> (relevant attribute in parenthesis)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -