You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
the function SetExpanded() doesn’t properly update the lenght of the page, I modified an example code to test this.
In this code I added a button that call SetExpanded(True) or SetExpanded(False) based on it’s current value, the lenght of the scrollbars is the sum of everything except the childs of “fonts” in this case
#!/usr/bin/env pythonimportsysimporttimeimportmathimportos.pathimportwximportwx.advimportwx.propgridaswxpgfromsiximportexec__=wx.GetTranslation############################################################################## TEST RELATED CODE AND VARIABLES#############################################################################default_object_content2="""\object.title = "Object Title"object.index = 1object.PI = %fobject.wxpython_rules = True"""%(math.pi)
default_object_content1="""\## Note that the results of autofill will appear on the second page.## Set number of iterations appropriately to test performanceiterations = 100## Test result for 100,000 iterations on Athlon XP 2000+:## Time spent per property: 0.054ms# Memory allocated per property: ~350 bytes (includes Python object)#for i in range(0,iterations): setattr(object,'title%i'%i,"Object Title") setattr(object,'index%i'%i,1) setattr(object,'PI%i'%i,3.14) setattr(object,'wxpython_rules%i'%i,True)"""############################################################################## CUSTOM PROPERTY SAMPLES#############################################################################classValueObject:
def__init__(self):
passclassIntProperty2(wxpg.PGProperty):
""" This is a simple re-implementation of wxIntProperty. """def__init__(self, label, name=wxpg.PG_LABEL, value=0):
wxpg.PGProperty.__init__(self, label, name)
self.SetValue(value)
defGetClassName(self):
""" This is not 100% necessary and in future is probably going to be automated to return class name. """return"IntProperty2"defDoGetEditorClass(self):
returnwxpg.PropertyGridInterface.GetEditorByName("TextCtrl")
defValueToString(self, value, flags):
returnstr(value)
defStringToValue(self, s, flags):
""" If failed, return False or (False, None). If success, return tuple (True, newValue). """try:
v=int(s)
ifself.GetValue() !=v:
return (True, v)
except (ValueError, TypeError):
ifflags&wxpg.PG_REPORT_ERROR:
wx.MessageBox("Cannot convert '%s' into a number."%s, "Error")
return (True, None)
defIntToValue(self, v, flags):
""" If failed, return False or (False, None). If success, return tuple (True, newValue). """if (self.GetValue() !=v):
return (True, v)
returnTruedefValidateValue(self, value, validationInfo):
""" Let's limit the value to range -10000 and 10000. """# Just test this function to make sure validationInfo and# wxPGVFBFlags work properly.oldvfb__=validationInfo.GetFailureBehavior()
# Mark the cell if validation failedvalidationInfo.SetFailureBehavior(wxpg.PG_VFB_MARK_CELL)
ifvalueisNoneorvalue<-10000orvalue>10000:
returnTruereturnTrueclassSizeProperty(wxpg.PGProperty):
""" Demonstrates a property with few children. """def__init__(self, label, name=wxpg.PG_LABEL, value=wx.Size(0, 0)):
wxpg.PGProperty.__init__(self, label, name)
value=self._ConvertValue(value)
self.AddPrivateChild( wxpg.IntProperty("X", value=value.x) )
self.AddPrivateChild( wxpg.IntProperty("Y", value=value.y) )
self.m_value=valuedefGetClassName(self):
returnself.__class__.__name__defDoGetEditorClass(self):
returnwxpg.PropertyGridInterface.GetEditorByName("TextCtrl")
defRefreshChildren(self):
size=self.m_valueself.Item(0).SetValue( size.x )
self.Item(1).SetValue( size.y )
def_ConvertValue(self, value):
""" Utility convert arbitrary value to a real wx.Size. """importcollectionsifisinstance(value, collections.abc.Sequence) orhasattr(value, '__getitem__'):
value=wx.Size(*value)
returnvaluedefChildChanged(self, thisValue, childIndex, childValue):
size=self._ConvertValue(self.m_value)
ifchildIndex==0:
size.x=childValueelifchildIndex==1:
size.y=childValueelse:
raiseAssertionErrorreturnsizeclassDirsProperty(wxpg.ArrayStringProperty):
""" Sample of a custom custom ArrayStringProperty. Because currently some of the C++ helpers from wxArrayStringProperty and wxProperytGrid are not available, our implementation has to quite a bit 'manually'. Which is not too bad since Python has excellent string and list manipulation facilities. """def__init__(self, label, name=wxpg.PG_LABEL, value=[]):
wxpg.ArrayStringProperty.__init__(self, label, name, value)
self.m_display=''# Set default delimiterself.SetAttribute("Delimiter", ',')
# NOTE: In the Classic version of the propgrid classes, all of the wrapped# property classes override DoGetEditorClass so it calls GetEditor and# looks up the class using that name, and hides DoGetEditorClass from the# usable API. Jumping through those hoops is no longer needed in Phoenix# as Phoenix allows overriding all necessary virtual methods without# special support in the wrapper code, so we just need to override# DoGetEditorClass here instead.defDoGetEditorClass(self):
returnwxpg.PropertyGridInterface.GetEditorByName("TextCtrlAndButton")
defValueToString(self, value, flags):
# let's just use the cached display valuereturnself.m_displaydefOnSetValue(self):
self.GenerateValueAsString()
defDoSetAttribute(self, name, value):
retval=super(DirsProperty, self).DoSetAttribute(name, value)
# Must re-generate cached string when delimiter changesifname=="Delimiter":
self.GenerateValueAsString(delim=value)
returnretvaldefGenerateValueAsString(self, delim=None):
""" This function creates a cached version of displayed text (self.m_display). """ifnotdelim:
delim=self.GetAttribute("Delimiter")
ifnotdelim:
delim=','ls=self.GetValue()
ifdelim=='"'ordelim=="'":
text=' '.join(['%s%s%s'%(delim,a,delim) forainls])
else:
text=', '.join(ls)
self.m_display=textdefStringToValue(self, text, argFlags):
""" If failed, return False or (False, None). If success, return tuple (True, newValue). """delim=self.GetAttribute("Delimiter")
ifdelim=='"'ordelim=="'":
# Proper way to call same method from super classreturnsuper(DirsProperty, self).StringToValue(text, 0)
v= [a.strip() foraintext.split(delim)]
return (True, v)
defOnEvent(self, propgrid, primaryEditor, event):
ifevent.GetEventType() ==wx.wxEVT_COMMAND_BUTTON_CLICKED:
dlg=wx.DirDialog(propgrid,
_("Select a directory to be added to ""the list:"))
ifdlg.ShowModal() ==wx.ID_OK:
new_path=dlg.GetPath()
old_value=self.m_valueifold_value:
new_value=list(old_value)
new_value.append(new_path)
else:
new_value= [new_path]
self.SetValueInEvent(new_value)
retval=Trueelse:
retval=Falsedlg.Destroy()
returnretvalreturnFalseclassPyObjectPropertyValue:
""" Value type of our sample PyObjectProperty. We keep a simple dash-delimited list of string given as argument to constructor. """def__init__(self, s=None):
try:
self.ls= [a.strip() forains.split('-')]
except:
self.ls= []
def__repr__(self):
return' - '.join(self.ls)
classPyObjectProperty(wxpg.PGProperty):
""" Another simple example. This time our value is a PyObject. NOTE: We can't return an arbitrary python object in DoGetValue. It cannot be a simple type such as int, bool, double, or string, nor an array or wxObject based. Dictionary, None, or any user-specified Python class is allowed. """def__init__(self, label, name=wxpg.PG_LABEL, value=None):
wxpg.PGProperty.__init__(self, label, name)
self.SetValue(value)
defGetClassName(self):
returnself.__class__.__name__defGetEditor(self):
return"TextCtrl"defValueToString(self, value, flags):
returnrepr(value)
defStringToValue(self, s, flags):
""" If failed, return False or (False, None). If success, return tuple (True, newValue). """v=PyObjectPropertyValue(s)
return (True, v)
classSampleMultiButtonEditor(wxpg.PGTextCtrlEditor):
def__init__(self):
wxpg.PGTextCtrlEditor.__init__(self)
defCreateControls(self, propGrid, property, pos, sz):
# Create and populate buttons-subwindowbuttons=wxpg.PGMultiButton(propGrid, sz)
# Add two regular buttonsbuttons.AddButton("...")
buttons.AddButton("A")
# Add a bitmap buttonbuttons.AddBitmapButton(wx.ArtProvider.GetBitmap(wx.ART_FOLDER))
# Create the 'primary' editor control (textctrl in this case)wnd=super(SampleMultiButtonEditor, self).CreateControls(
propGrid,
property,
pos,
buttons.GetPrimarySize())
wnd=wnd.GetPrimary()
# Finally, move buttons-subwindow to correct position and make sure# returned wxPGWindowList contains our custom button list.buttons.Finalize(propGrid, pos);
# We must maintain a reference to any editor objects we created# ourselves. Otherwise they might be freed prematurely. Also,# we need it in OnEvent() below, because in Python we cannot "cast"# result of wxPropertyGrid.GetEditorControlSecondary() into# PGMultiButton instance.self.buttons=buttonsreturnwxpg.PGWindowList(wnd, buttons)
defOnEvent(self, propGrid, prop, ctrl, event):
ifevent.GetEventType() ==wx.wxEVT_COMMAND_BUTTON_CLICKED:
buttons=self.buttonsevtId=event.GetId()
ifevtId==buttons.GetButtonId(0):
# Do something when the first button is pressedwx.LogDebug("First button pressed")
returnFalse# Return false since value did not changeifevtId==buttons.GetButtonId(1):
# Do something when the second button is pressedwx.MessageBox("Second button pressed")
returnFalse# Return false since value did not changeifevtId==buttons.GetButtonId(2):
# Do something when the third button is pressedwx.MessageBox("Third button pressed")
returnFalse# Return false since value did not changereturnsuper(SampleMultiButtonEditor, self).OnEvent(propGrid, prop, ctrl, event)
classSingleChoiceDialogAdapter(wxpg.PGEditorDialogAdapter):
""" This demonstrates use of wxpg.PGEditorDialogAdapter. """def__init__(self, choices):
wxpg.PGEditorDialogAdapter.__init__(self)
self.choices=choicesdefDoShowDialog(self, propGrid, property):
s=wx.GetSingleChoice("Message", "Caption", self.choices)
ifs:
self.SetValue(s)
returnTruereturnFalse;
classSingleChoiceProperty(wxpg.StringProperty):
def__init__(self, label, name=wxpg.PG_LABEL, value=''):
wxpg.StringProperty.__init__(self, label, name, value)
# Prepare choicesdialog_choices= []
dialog_choices.append("Cat")
dialog_choices.append("Dog")
dialog_choices.append("Gibbon")
dialog_choices.append("Otter")
self.dialog_choices=dialog_choicesdefDoGetEditorClass(self):
returnwxpg.PropertyGridInterface.GetEditorByName("TextCtrlAndButton")
defGetEditorDialog(self):
# Set what happens on button clickreturnSingleChoiceDialogAdapter(self.dialog_choices)
classTrivialPropertyEditor(wxpg.PGEditor):
""" This is a simple re-creation of TextCtrlWithButton. Note that it does not take advantage of wx.TextCtrl and wx.Button creation helper functions in wx.PropertyGrid. """def__init__(self):
wxpg.PGEditor.__init__(self)
defCreateControls(self, propgrid, property, pos, sz):
""" Create the actual wxPython controls here for editing the property value. You must use propgrid.GetPanel() as parent for created controls. Return value is either single editor control or tuple of two editor controls, of which first is the primary one and second is usually a button. """try:
x, y=posw, h=szh=64+6# Make room for buttonbw=propgrid.GetRowHeight()
w-=bws=property.GetDisplayedString();
tc=wx.TextCtrl(propgrid.GetPanel(), wx.ID_ANY, s,
(x,y), (w,h),
wx.TE_PROCESS_ENTER)
btn=wx.Button(propgrid.GetPanel(), wx.ID_ANY, '...',
(x+w, y),
(bw, h), wx.WANTS_CHARS)
returnwxpg.PGWindowList(tc, btn)
except:
importtracebackprint(traceback.print_exc())
defUpdateControl(self, property, ctrl):
ctrl.SetValue(property.GetDisplayedString())
defDrawValue(self, dc, rect, property, text):
ifnotproperty.IsValueUnspecified():
dc.DrawText(property.GetDisplayedString(), rect.x+5, rect.y)
defOnEvent(self, propgrid, property, ctrl, event):
""" Return True if modified editor value should be committed to the property. To just mark the property value modified, call propgrid.EditorsValueWasModified(). """ifnotctrl:
returnFalseevtType=event.GetEventType()
ifevtType==wx.wxEVT_COMMAND_TEXT_ENTER:
ifpropgrid.IsEditorsValueModified():
returnTrueelifevtType==wx.wxEVT_COMMAND_TEXT_UPDATED:
## Pass this event outside wxPropertyGrid so that,# if necessary, program can tell when user is editing# a textctrl.event.Skip()
event.SetId(propgrid.GetId())
propgrid.EditorsValueWasModified()
returnFalsereturnFalsedefGetValueFromControl(self, property, ctrl):
""" Return tuple (wasSuccess, newValue), where wasSuccess is True if different value was acquired successfully. """tc=ctrltextVal=tc.GetValue()
ifproperty.UsesAutoUnspecified() andnottextVal:
return (True, None)
res, value=property.StringToValue(textVal, wxpg.PG_FULL_VALUE)
# Changing unspecified always causes event (returning# True here should be enough to trigger it).ifnotresandvalueisNone:
res=Truereturn (res, value)
defSetValueToUnspecified(self, property, ctrl):
ctrl.Remove(0,len(ctrl.GetValue()))
defSetControlStringValue(self, property, ctrl, text):
ctrl.SetValue(text)
defOnFocus(self, property, ctrl):
ctrl.SetSelection(-1,-1)
classLargeImageEditor(wxpg.PGEditor):
""" Double-height text-editor with image in front. """def__init__(self):
wxpg.PGEditor.__init__(self)
defCreateControls(self, propgrid, property, pos, sz):
try:
x, y=posw, h=szh=64+6# Make room for buttonbw=propgrid.GetRowHeight()
w-=bwself.property=propertyself.RefreshThumbnail()
self.statbmp=wx.StaticBitmap(propgrid.GetPanel(), -1, self.bmp, (x,y))
self.tc=wx.TextCtrl(propgrid.GetPanel(), -1, "",
(x+h,y), (2048,h), wx.BORDER_NONE)
btn=wx.Button(propgrid.GetPanel(), wx.ID_ANY, '...',
(x+w, y),
(bw, h), wx.WANTS_CHARS)
# When the textctrl is destroyed, destroy the statbmp toodef_cleanupStatBmp(evt):
ifself.statbmp:
self.statbmp.Destroy()
self.tc.Bind(wx.EVT_WINDOW_DESTROY, _cleanupStatBmp)
returnwxpg.PGWindowList(self.tc, btn)
except:
importtracebackprint(traceback.print_exc())
defGetName(self):
return"LargeImageEditor"defUpdateControl(self, property, ctrl):
s=property.GetDisplayedString()
self.tc.SetValue(s)
self.RefreshThumbnail()
self.statbmp.SetBitmap(self.bmp)
defDrawValue(self, dc, rect, property, text):
ifnotproperty.IsValueUnspecified():
dc.DrawText(property.GetDisplayedString(), rect.x+5, rect.y)
defOnEvent(self, propgrid, property, ctrl, event):
""" Return True if modified editor value should be committed to the property. To just mark the property value modified, call propgrid.EditorsValueWasModified(). """ifnotctrl:
returnFalseevtType=event.GetEventType()
ifevtType==wx.wxEVT_COMMAND_TEXT_ENTER:
ifpropgrid.IsEditorsValueModified():
returnTrueelifevtType==wx.wxEVT_COMMAND_TEXT_UPDATED:
## Pass this event outside wxPropertyGrid so that,# if necessary, program can tell when user is editing# a textctrl.event.Skip()
event.SetId(propgrid.GetId())
propgrid.EditorsValueWasModified()
returnFalsereturnFalsedefGetValueFromControl(self, property, ctrl):
""" Return tuple (wasSuccess, newValue), where wasSuccess is True if different value was acquired successfully. """textVal=self.tc.GetValue()
ifproperty.UsesAutoUnspecified() andnottextVal:
return (None, True)
res, value=property.StringToValue(textVal,
wxpg.PG_EDITABLE_VALUE)
# Changing unspecified always causes event (returning# True here should be enough to trigger it).ifnotresandvalueisNone:
res=Truereturn (res, value)
defSetValueToUnspecified(self, property, ctrl):
ctrl.Remove(0, len(ctrl.GetValue()))
self.RefreshThumbnail()
self.statbmp.SetBitmap(self.bmp)
defSetControlStringValue(self, property, ctrl, txt):
self.tc.SetValue(txt)
self.RefreshThumbnail()
self.statbmp.SetBitmap(self.bmp)
defCanContainCustomImage(self):
returnTruedefRefreshThumbnail(self):
""" We use here very simple image scaling code. """def_makeEmptyBmp():
bmp=wx.Bitmap(64,64)
dc=wx.MemoryDC()
dc.SelectObject(bmp)
dc.SetPen(wx.Pen(wx.BLACK))
dc.SetBrush(wx.WHITE_BRUSH)
dc.DrawRectangle(0, 0, 64, 64)
returnbmpifnotself.property:
self.bmp=_makeEmptyBmp()
returnpath=self.property.DoGetValue()
ifnotos.path.isfile(path):
self.bmp=_makeEmptyBmp()
returnimage=wx.Image(path)
image.Rescale(64, 64)
self.bmp=wx.Bitmap(image)
############################################################################## MAIN PROPERTY GRID TEST PANEL#############################################################################classTestPanel( wx.Panel ):
def__init__( self, parent, log ):
wx.Panel.__init__(self, parent, wx.ID_ANY)
self.log=logself.panel=panel=wx.Panel(self, wx.ID_ANY)
topsizer=wx.BoxSizer(wx.VERTICAL)
# Difference between using PropertyGridManager vs PropertyGrid is that# the manager supports multiple pages and a description box.self.pg=pg=wxpg.PropertyGridManager(panel,
style=wxpg.PG_SPLITTER_AUTO_CENTER|wxpg.PG_AUTO_SORT|wxpg.PG_TOOLBAR)
# Show help as tooltipspg.ExtraStyle |= wxpg.PG_EX_HELP_AS_TOOLTIPSpg.Bind( wxpg.EVT_PG_CHANGED, self.OnPropGridChange )
pg.Bind( wxpg.EVT_PG_PAGE_CHANGED, self.OnPropGridPageChange )
pg.Bind( wxpg.EVT_PG_SELECTED, self.OnPropGridSelect )
pg.Bind( wxpg.EVT_PG_RIGHT_CLICK, self.OnPropGridRightClick )
## Let's use some simple custom editor## NOTE: Editor must be registered *before* adding a property that# uses it.ifnotgetattr(sys, '_PropGridEditorsRegistered', False):
pg.RegisterEditor(TrivialPropertyEditor)
pg.RegisterEditor(SampleMultiButtonEditor)
pg.RegisterEditor(LargeImageEditor)
# ensure we only do it oncesys._PropGridEditorsRegistered=True## Add properties## NOTE: in this example the property names are used as variable names# in one of the tests, so they need to be valid python identifiers.#pg.AddPage( "Page 1 - Testing All" )
pg.Append( wxpg.PropertyCategory("1 - Basic Properties") )
pg.Append( wxpg.StringProperty("String",value="Some Text") )
sp=pg.Append( wxpg.StringProperty('StringProperty_as_Password', value='ABadPassword') )
sp.SetAttribute('Hint', 'This is a hint')
sp.SetAttribute('Password', True)
pg.Append( wxpg.IntProperty("Int", value=100) )
self.fprop=pg.Append( wxpg.FloatProperty("Float", value=123.456) )
pg.Append( wxpg.BoolProperty("Bool", value=True) )
boolprop=pg.Append( wxpg.BoolProperty("Bool_with_Checkbox", value=True) )
pg.SetPropertyAttribute(
"Bool_with_Checkbox", # You can find the property by name,#boolprop, # or give the property object itself."UseCheckbox", True) # The attribute name and valuepg.Append( wxpg.PropertyCategory("2 - More Properties") )
pg.Append( wxpg.LongStringProperty("LongString",
value="This is a\nmulti-line string\nwith\ttabs\nmixed\tin."))
pg.Append( wxpg.DirProperty("Dir",value=r"C:\Windows") )
pg.Append( wxpg.FileProperty("File",value=r"C:\Windows\system.ini") )
pg.Append( wxpg.ArrayStringProperty("ArrayString",value=['A','B','C']) )
pg.Append( wxpg.EnumProperty("Enum","Enum",
['wxPython Rules',
'wxPython Rocks',
'wxPython Is The Best'],
[10,11,12],
0) )
pg.Append( wxpg.EditEnumProperty("EditEnum","EditEnumProperty",
['A','B','C'],
[0,1,2],
"Text Not in List") )
pg.Append( wxpg.PropertyCategory("3 - Advanced Properties") )
pg.Append( wxpg.DateProperty("Date",value=wx.DateTime.Now()) )
font=wxpg.FontProperty("Font", name="Font", value=panel.GetFont())
pg.Append( font )
# When page is added, it will become the target page for AutoFill# calls (and for other property insertion methods as well)pg.AddPage( "Page 2 - Results of AutoFill will appear here" )
topsizer.Add(pg, 1, wx.EXPAND)
rowsizer=wx.BoxSizer(wx.HORIZONTAL)
but=wx.Button(panel,-1,"SetPropertyValues")
but.Bind( wx.EVT_BUTTON, self.OnSetPropertyValues )
rowsizer.Add(but,1)
but=wx.Button(panel,-1,"GetPropertyValues")
but.Bind( wx.EVT_BUTTON, self.OnGetPropertyValues )
rowsizer.Add(but,1)
topsizer.Add(rowsizer,0,wx.EXPAND)
rowsizer=wx.BoxSizer(wx.HORIZONTAL)
but=wx.Button(panel,-1,"GetPropertyValues(as_strings=True)")
but.Bind( wx.EVT_BUTTON, self.OnGetPropertyValues2 )
rowsizer.Add(but,1)
but=wx.Button(panel,-1,"AutoFill")
but.Bind( wx.EVT_BUTTON, self.OnAutoFill )
rowsizer.Add(but,1)
topsizer.Add(rowsizer,0,wx.EXPAND)
rowsizer=wx.BoxSizer(wx.HORIZONTAL)
but=wx.Button(panel,-1,"Delete")
but.Bind( wx.EVT_BUTTON, self.OnDeleteProperty )
rowsizer.Add(but,1)
but=wx.Button(panel,-1,"Run Tests")
but.Bind( wx.EVT_BUTTON, self.RunTests )
rowsizer.Add(but,1)
topsizer.Add(rowsizer,0,wx.EXPAND)
but=wx.Button(panel,-1,"expand font")
but.Bind( wx.EVT_BUTTON, self.expandFont)
rowsizer.Add(but,1)
topsizer.Add(rowsizer,0,wx.EXPAND)
panel.SetSizer(topsizer)
topsizer.SetSizeHints(panel)
sizer=wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel, 1, wx.EXPAND)
self.SetSizer(sizer)
self.SetAutoLayout(True)
defOnPropGridChange(self, event):
p=event.GetProperty()
ifp:
self.log.write('%s changed to "%s"\n'% (p.GetName(),p.GetValueAsString()))
defOnPropGridSelect(self, event):
p=event.GetProperty()
ifp:
self.log.write('%s selected\n'% (event.GetProperty().GetName()))
else:
self.log.write('Nothing selected\n')
defOnDeleteProperty(self, event):
p=self.pg.GetSelectedProperty()
ifp:
self.pg.DeleteProperty(p)
else:
wx.MessageBox("First select a property to delete")
defOnReserved(self, event):
passdefOnSetPropertyValues(self,event):
try:
d=self.pg.GetPropertyValues(inc_attributes=True)
ss= []
fork,vind.items():
v=repr(v)
ifnotvorv[0] !='<':
ifk.startswith('@'):
ss.append('setattr(obj, "%s", %s)'%(k,v))
else:
ss.append('obj.%s = %s'%(k,v))
withMemoDialog(self,
"Enter Content for Object Used in SetPropertyValues",
'\n'.join(ss)) asdlg: # default_object_content1ifdlg.ShowModal() ==wx.ID_OK:
importdatetimesandbox= {'obj':ValueObject(),
'wx':wx,
'datetime':datetime}
exec_(dlg.tc.GetValue(), sandbox)
t_start=time.time()
#print(sandbox['obj'].__dict__)self.pg.SetPropertyValues(sandbox['obj'])
t_end=time.time()
self.log.write('SetPropertyValues finished in %.0fms\n'%
((t_end-t_start)*1000.0))
except:
importtracebacktraceback.print_exc()
defOnGetPropertyValues(self,event):
try:
t_start=time.time()
d=self.pg.GetPropertyValues(inc_attributes=True)
t_end=time.time()
self.log.write('GetPropertyValues finished in %.0fms\n'%
((t_end-t_start)*1000.0))
ss= ['%s: %s'%(k,repr(v)) fork,vind.items()]
withMemoDialog(self,"GetPropertyValues Result",
'Contents of resulting dictionary:\n\n'+'\n'.join(ss)) asdlg:
dlg.ShowModal()
except:
importtracebacktraceback.print_exc()
defOnGetPropertyValues2(self,event):
try:
t_start=time.time()
d=self.pg.GetPropertyValues(as_strings=True)
t_end=time.time()
self.log.write('GetPropertyValues(as_strings=True) finished in %.0fms\n'%
((t_end-t_start)*1000.0))
ss= ['%s: %s'%(k,repr(v)) fork,vind.items()]
withMemoDialog(self,"GetPropertyValues Result",
'Contents of resulting dictionary:\n\n'+'\n'.join(ss)) asdlg:
dlg.ShowModal()
except:
importtracebacktraceback.print_exc()
defOnAutoFill(self,event):
try:
withMemoDialog(self,"Enter Content for Object Used for AutoFill",default_object_content1) asdlg:
ifdlg.ShowModal() ==wx.ID_OK:
sandbox= {'object':ValueObject(),'wx':wx}
exec_(dlg.tc.GetValue(), sandbox)
t_start=time.time()
self.pg.AutoFill(sandbox['object'])
t_end=time.time()
self.log.write('AutoFill finished in %.0fms\n'%
((t_end-t_start)*1000.0))
except:
importtracebacktraceback.print_exc()
defOnPropGridRightClick(self, event):
p=event.GetProperty()
ifp:
self.log.write('%s right clicked\n'% (event.GetProperty().GetName()))
else:
self.log.write('Nothing right clicked\n')
defOnPropGridPageChange(self, event):
index=self.pg.GetSelectedPage()
self.log.write('Page Changed to \'%s\'\n'% (self.pg.GetPageName(index)))
defexpandFont(self, event):
font=self.pg.GetPropertyByName("Font")
iffont.IsExpanded():
font.SetExpanded(False)
self.pg.Refresh()
self.pg.Update()
else:
font.SetExpanded(True)
self.pg.Refresh()
self.pg.Update()
defRunTests(self, event):
pg=self.pglog=self.log# Validate client datalog.write('Testing client data set/get')
pg.SetPropertyClientData( "Bool", 1234 )
ifpg.GetPropertyClientData( "Bool" ) !=1234:
raiseValueError("Set/GetPropertyClientData() failed")
# Test setting unicode stringlog.write('Testing setting an unicode string value')
pg.GetPropertyByName("String").SetValue(u"Some Unicode Text")
## Test some code that *should* fail (but not crash)try:
ifwx.GetApp().GetAssertionMode() ==wx.PYAPP_ASSERT_EXCEPTION:
log.write('Testing exception handling compliancy')
a_=pg.GetPropertyValue( "NotARealProperty" )
pg.EnableProperty( "NotAtAllRealProperty", False )
pg.SetPropertyHelpString("AgaintNotARealProperty",
"Dummy Help String" )
except:
pass# GetPyIteratorlog.write('GetPage(0).GetPyIterator()\n')
it=pg.GetPage(0).GetPyIterator(wxpg.PG_ITERATE_ALL)
forpropinit:
log.write('Iterating \'%s\'\n'% (prop.GetName()))
# VIteratorlog.write('GetPyVIterator()\n')
it=pg.GetPyVIterator(wxpg.PG_ITERATE_ALL)
forpropinit:
log.write('Iterating \'%s\'\n'% (prop.GetName()))
# Propertieslog.write('GetPage(0).Properties\n')
it=pg.GetPage(0).Propertiesforpropinit:
log.write('Iterating \'%s\'\n'% (prop.GetName()))
# Itemslog.write('GetPage(0).Items\n')
it=pg.GetPage(0).Itemsforpropinit:
log.write('Iterating \'%s\'\n'% (prop.GetName()))
#---------------------------------------------------------------------------classMemoDialog(wx.Dialog):
""" Dialog for multi-line text editing. """def__init__(self,parent=None,title="",text="",pos=None,size=(500,500)):
wx.Dialog.__init__(self,parent,-1,title,style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
topsizer=wx.BoxSizer( wx.VERTICAL )
tc=wx.TextCtrl(self,11,text,style=wx.TE_MULTILINE)
self.tc=tctopsizer.Add(tc,1,wx.EXPAND|wx.ALL,8)
rowsizer=wx.BoxSizer( wx.HORIZONTAL )
rowsizer.Add(wx.Button(self,wx.ID_OK,'Ok'),0,wx.ALIGN_CENTRE_VERTICAL,8)
rowsizer.Add((0,0),1,wx.ALIGN_CENTRE_VERTICAL,8)
rowsizer.Add(wx.Button(self,wx.ID_CANCEL,'Cancel'),0,wx.ALIGN_CENTRE_VERTICAL,8)
topsizer.Add(rowsizer,0,wx.EXPAND|wx.ALL,8)
self.SetSizer( topsizer )
topsizer.Layout()
self.SetSize( size )
ifnotpos:
self.CenterOnScreen()
else:
self.Move(pos)
#----------------------------------------------------------------------defrunTest( frame, nb, log ):
win=TestPanel( nb, log )
returnwin#----------------------------------------------------------------------overview="""\<html><body><P>This demo shows all basic wxPropertyGrid properties, in addition tosome custom property classes.</body></html>"""if__name__=='__main__':
importsys,osimportrunrun.main(['', os.path.basename(sys.argv[0])] +sys.argv[1:])
The text was updated successfully, but these errors were encountered:
the function SetExpanded() doesn’t properly update the lenght of the page, I modified an example code to test this.
In this code I added a button that call SetExpanded(True) or SetExpanded(False) based on it’s current value, the lenght of the scrollbars is the sum of everything except the childs of “fonts” in this case
The text was updated successfully, but these errors were encountered: