I've made an add-on with several ATCTContent, all created with paster addcontent contenttype. All but one, GearContent work as expected. Only when I create instances of GearContent they receive names like gear, gear-1, etc. ignoring the title. In default view, the H1 tag is always 'Gear' but the title bellow it is right.
Trying to change the ids and titles on the folder content view doesn't do anything. There's no error message.
Same thing with the catalog. GearContent's Title metadata is 'Gear' for all instances. It works for all other types.
GearContent is only addable inside GearFolder. Other contents have similar restrictions and work fine. I'm using plone 4.0.4.
What can I do to make new instances get the title right?
Below content/gearcontent.py:
"""Definition of the Gear Content content type
"""
from zope.interface import implements
from Products.Archetypes import atapi
from Products.ATContentTypes.content import base
from Products.ATContentTypes.content import schemata
# -*- Message Factory Imported Here -*-
from levity7.gears import gearsMessageFactory as _
from levity7.gears.interfaces import IGearContent
from levity7.gears.config import PROJECTNAME
GearContentSchema = schemata.ATContentTypeSchema.copy() + atapi.Schema((
# -*- Your Archetypes field definitions here ... -*-
atapi.StringField(
'title',
storage=atapi.AnnotationStorage(),
widget=atapi.StringWidget(
label=_(u"Title"),
description=_(u"Name for this content."),
),
required=True,
),
atapi.ReferenceField(
'activities',
storage=atapi.AnnotationStorage(),
widget=atapi.ReferenceWidget(
label=_(u"Adventure Activities"),
description=_(u"Select all activities that apply to this content."),
),
required=True,
relationship='gearcontent_activities',
allowed_types=('Gear Activity'), # specify portal type names here ('Example Type',)
multiValued=True,
),
atapi.ReferenceField(
'category',
storage=atapi.AnnotationStorage(),
widget=atapi.ReferenceWidget(
label=_(u"Category"),
description=_(u"Select a category for this content."),
),
required=True,
relationship='gearcontent_category',
allowed_types=('Gear Category'), # specify portal type names here ('Example Type',)
multiValued=False,
),
atapi.ImageField(
'image',
storage=atapi.AnnotationStorage(),
widget=atapi.ImageWidget(
label=_(u"Image"),
description=_(u"A picture of this content."),
),
validators=('isNonEmptyFile'),
),
atapi.StringField(
'imageLink',
storage=atapi.AnnotationStorage(),
widget=atapi.StringWidget(
label=_(u"Image Link"),
description=_(u"An URL to the image of this content."),
),
validators=('isURL'),
),
atapi.TextField(
'description',
storage=atapi.AnnotationStorage(),
widget=atapi.RichWidget(
label=_(u"Description"),
description=_(u"Description for the content."),
),
required=True,
),
atapi.StringField(
'reviewLink',
storage=atapi.AnnotationStorage(),
widget=atapi.StringWidget(
label=_(u"Review Link"),
description=_(u"Link to Review page."),
),
validators=('isURL'),
),
atapi.StringField(
'diyLink',
storage=atapi.AnnotationStorage(),
widget=atapi.StringWidget(
label=_(u"DIY Link"),
description=_(u"Link to DIY page."),
),
validators=('isURL'),
),
atapi.TextField(
'commentary',
storage=atapi.AnnotationStorage(),
widget=atapi.TextAreaWidget(
label=_(u"commentary"),
description=_(u"commentarys for the content. These will not be displayed."),
),
),
atapi.TextField(
'purchaseHtml',
storage=atapi.AnnotationStorage(),
widget=atapi.TextAreaWidget(
label=_(u"Purchase HTML Code"),
description=_(u"HTML used to display or add this item to the Cart."),
),
),
atapi.IntegerField(
'score',
storage=atapi.AnnotationStorage(),
widget=atapi.IntegerWidget(
label=_(u"Life This Value"),
description=_(u"Initial value of 'Life This'"),
),
default=_(u"0"),
validators=('isInt'),
),
))
# Set storage on fields copied from ATContentTypeSchema, making sure
# they work well with the python bridge properties.
GearContentSchema['title'].storage = atapi.AnnotationStorage()
GearContentSchema['description'].storage = atapi.AnnotationStorage()
schemata.finalizeATCTSchema(GearContentSchema, moveDiscussion=False)
class GearContent(base.ATCTContent):
"""Gear Content"""
implements(IGearContent)
meta_type = "GearContent"
schema = GearContentSchema
title = atapi.ATFieldProperty('title')
description = atapi.ATFieldProperty('description')
# -*- Your ATSchema to Python Property Bridges Here ... -*-
title = atapi.ATFieldProperty('title')
activities = atapi.ATReferenceFieldProperty('activities')
category = atapi.ATReferenceFieldProperty('category')
image = atapi.ATFieldProperty('image')
imageLink = atapi.ATFieldProperty('imageLink')
description = atapi.ATFieldProperty('description')
reviewLink = atapi.ATFieldProperty('reviewLink')
diyLink = atapi.ATFieldProperty('diyLink')
commentary = atapi.ATFieldProperty('commentary')
purchaseHtml = atapi.ATFieldProperty('purchaseHtml')
score = atapi.ATFieldProperty('score')
atapi.registerType(GearContent, PROJECTNAME)
Thanks.
Remove your "title" field. It's already defined in ATContentTypeSchema. You're effectively re-implementing it, but without the baseline functionality like automatic content object naming. Yours is masking the one defined in Archetypes.
The problem was in the field category. It seems that's a reserved name. (in the above it appears 'categoty'; it was a typo).
Related
I am getting Value Error:
The 'specs' argument to make_subplots must be a 2D list of dictionaries with dimensions (1 x 1).
Received value of type <class 'list'>: [[{'secondary_y': False}], [{'secondary_y': True}], [{'colspan': 1}, None]]
I refer to the existing post plotly subplots issue with specs, value error and followed the same but error still persists.
Below is the code snippet:
import talib as ta
import yfinance as yf
import pandas as pd
import plotly.io as pio
pio.renderers.default='browser'
import plotly.graph_objects as go
from plotly.subplots import make_subplots
'''
Extracting the data
'''
VIP = yf.Ticker('VIPIND.NS')
df = VIP.history(period="max")
df.reset_index(inplace = True)
df['Date'] = pd.to_datetime(df['Date'])
'''
Creating the technical indicators
'''
df['EMA_Close'] = ta.EMA(df.Close,100)
df['MA_Close'] = ta.MA(df.Close,60)
df['MACD'],df['MACDsig'],df['MACDhist']=ta.MACD(df.Close,30,60,15)
'''
###############################
Creating Plots
###############################
'''
'''
Declaring subplots
'''
fig = make_subplots(rows=2, cols=1)#, shared_xaxes=True,print_grid=True)
fig = make_subplots(specs=[[{"secondary_y": False}],[{"secondary_y": True}],[{"colspan": 1}, None]])
'''
Ploting the first row with OHLC, EMA and MA lines
'''
fig.add_trace(go.Candlestick(x=df["Date"], open=df["Open"], high=df["High"],
low=df["Low"], close=df["Close"], name="OHLC",showlegend=True),
row=1, col=1,secondary_y=False)
fig.add_trace(go.Scatter(x=df['Date'], y=df['EMA_Close'], showlegend=True,
name="EMA Close",line=dict(color="MediumPurple")
), row=1, col=1,secondary_y=False)
fig.add_trace(go.Scatter(x=df['Date'], y=df['MA_Close'], showlegend=True,
name="MA Close",line=dict(color="Orange")
), row=1, col=1,secondary_y=False)
'''
Ploting the second row with MACD & MACDSig lines and MACDHist as histogram/bar
'''
fig.add_trace(go.Bar(x=df.Date,
y=df['MACDhist'],showlegend=True,name="MACD Hist",marker=dict(color='black')
), row=2, col=1,secondary_y=False)
fig.add_trace(go.Scatter(x=df['Date'], y=df['MACDsig'], showlegend=True,
name="MACD Signal",line=dict(color="MediumPurple")
), row=2, col=1,secondary_y=True)
fig.add_trace(go.Scatter(x=df['Date'], y=df['MACD'], showlegend=True,
name="MACD",line=dict(color="red")
), row=2, col=1,secondary_y=True)
'''
Upadting the layout of the plot
'''
fig.update(layout_xaxis_rangeslider_visible=False)
fig.update_layout(height=600, width=1250)
fig.update_layout(
title='OHLC and Volume',
yaxis_title='Prices (Rs)',
xaxis_title='Dates')
fig.update_layout(template="plotly_white")
fig.update_layout(
margin=dict(l=20, r=20, t=40,b=20),)
# Providing desired Fonts for the plots
fig.update_layout(
font_family="Courier New",
font_color="blue",
title_font_family="Times New Roman",
title_font_color="red",
legend_title_font_color="green")
fig.show()
Requesting guidance on where am I going wrong.
Regards
Sudhir
You are getting the error because the dimension of your specs does not match the number of rows and cols you defined in your subplot. You have 2 rows and 1 col, which means your specs must be a list with 2x1 shape (i.e. a list of two lists. Here is an example:
specs=[[{"secondary_y": True, "colspan": X, "rowspan": X, "b": 0.05, etc}] ,
[{"secondary_y": False}]]).
Also, keep in mind the max value that colspan can take is the value you define for the col parameter. Finally, if you need to pass more settings for each subplot you can simply add them inside their corresponding dictionary
I want to retrieve and calculate input values from the textfield in listview .. how to achieve that?
You should define a list of TextEditingController with the same length of your listview, then assign each TextField in your list an object of this array, which will enable you to retrieve the value whether when editing or when completed. This is an example of what I've said :
List<TextEditingController> textFieldControllers ;
in your list :
textFieldControllers[index] = new TextEditingController() ;
new TextField(controller: textFieldControllers[index]);
after that you can retrieve the value by :
textFieldControllers[index].text
Brilliant. Added some stuff below to suit my use case.
First define a List like so List<TextEditingController> textFieldControllers=[];
then iterate through the the list used in creating the widgets in the List.builder like so.
for (var i = 0; i < typesItem.length; i++) {
textFieldControllers.add(TextEditingController());
}
where typesItem is the List item used in creating the Listbuilder widgets so as to maintain same lenght with your widgets dynamically.You can run this code on your initState method
there after goto your List.builder widget and initialise your controller like so.
textFieldControllers[index] = TextEditingController() ;
and set your TextField controllers in your return method like so
textFieldControllers[index]
You can therefore get all your value by using
textFieldControllers[index].text;
You can manipulate to suit use your case as you want
List<TextEditingController> machPresent=[];
machPresent.add(TextEditingController(text: ''));
Container(
height: mainScreenHeight * 0.06,
width: mainScreenWidth * 0.3,
child: TextFormField(
keyboardType: TextInputType.number,
controller: machPresent[index],
enabled: true,
textAlign: TextAlign.center,
),
),
),
Press an action from a button
Container(
height: mainScreenHeight * 0.06,
width: mainScreenWidth * 0.3,
child: RaisedButton(
onPressed: () {
submitForm(index);},
child: Text('Submit',textAlign: TextAlign.center),
),
),
dynamic submitForm(int index) {
var machValue=machPresent[index].text;
var f= machValue;
print(f);
}
Result
I/flutter ( 7914): fff888- -- -- -Select Status
I/flutter ( 7914): sourav- -- -- -Select Status
Thank you for your help in advance.
I've setup shiny server on Ubuntu in Amazon Web Services. Everything is working correctly with other apps I've uploaded. However, I'm trying to use the package shinydashboards to create some dashboards. I'm running into an issue where the first submenu item is not being rendered.
You can see the app live in AWS here. https://www.ndperfsci.com/apps/TestApps/PerfSci_App/
It functions just fine in ShinyApps.io
https://webbphysprep.shinyapps.io/test/
Here is the exact code I'm using:
library('shiny')
library('shinydashboard')
# Sidebar #############################
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem('Catapult', tabName = 'menu_ctplt', icon = icon('circle-o'),
collapsible =
menuSubItem('Upload Files', tabName = 'submenu_ctplt_upload'),
menuSubItem('Edit Records', tabName = 'submenu_ctplt_edit')
)
),
sidebarMenu(
menuItem('Force Decks', tabName = 'menu_fd', icon = icon('circle-o'),
collapsible =
menuSubItem('Upload Files', tabName = 'submenu_fd_upload'),
menuSubItem('Edit Records', tabName = 'submenu_fd_edit')
)
)
)
# Body #############################
body <- dashboardBody(
tabItems(
tabItem(tabName = 'submenu_ctplt_upload',
h2('Selected Sub-Item One')
),
tabItem(tabName = 'submenu_ctplt_edit',
h2('Selected Sub-Item Two')
),
tabItem(tabName = 'submenu_fd_upload',
h2('Selected Sub-Item Three')
),
tabItem(tabName = 'submenu_fd_edit',
h2('Selected Sub-Item Four')
)
)
)
# UI #############################
ui <- dashboardPage(
dashboardHeader(title = 'ND Perf-Sci Apps'),
skin = 'black',
sidebar,
body
)
# Server #############################
server <- function(input, output){
}
shinyApp(ui, server)
I am rendering a <Text> node in Flutter app something like:
We have total ${_summary['bookCount']} books.
_summary is retrieved via a remote API and bookCount is one of the returned JSON field. It normally is more than 1,000.
If I display the book count like that, it is a plain 1234. I would like to make it be shown as 1,234.
Currently, I have to manually modify that field using some formatter but this is cumbersome.
I am looking for something like:
We have total ${myNumberFormat(_summary['bookCount'])} books.
grammar, where myNumberFormat is a function.
In my previous programming in PHP and Twig, this can be done with a filter.
Much appreciate your input.
Update
#raju-bitter
This solution is what I know and is absolutely correct. What I am looking for is an inline "filter".
With this solution, a few things I don't like, the most of which is that, I have to split my one liner of text into several few segments:
We have {XXX} books, accumulating to {YYY} pages, and {ZZZ} word counts.
This sentence will be broken to 7 parts at least so that each number text section can be formatted via a formatter and then wrapped in a surrounding <Text>.
I am trying to see if there are more straightforward ways to do so.
There is a Dart package for formatting numbers, the Dart intl package. To use the package, add the following line to the Dart dependencies: pubspec.yaml file:
intl: ^0.17.0
Here's what my dependencies look like with the line:
dependencies:
flutter:
sdk: flutter
intl: ^0.17.0
Click packages get in IntelliJ, or run flutter packages get from the command line.
Make sure your class imports the intl package:
import 'package:intl/intl.dart' as intl;
In your code, you can use NumberFormat class to do the formatting:
final formatter = intl.NumberFormat.decimalPattern().format(1234) // formatted number will be: 1,234
Full stateful widget example:
class NumberFormatExample extends StatefulWidget {
#override
_NumberFormatExampleState createState() => new _NumberFormatExampleState();
}
class _NumberFormatExampleState extends State<NumberFormatExample> {
final formatter = intl.NumberFormat.decimalPattern();
int theValue = 1234;
#override
Widget build(BuildContext context) {
return new Text(formatter.format(theValue));
}
}
An update for above answers:
First add intl package into your pubspec.yaml file, just after flutter sdk (like below):
dependencies:
flutter:
sdk: flutter
intl: ^0.16.0
If you use flutter_localizations, intl must be above of that.
Now you can use NumberFormat class.
Some examples:
print(NumberFormat.currency().format(123456)); // USD123,456.00
print(NumberFormat.currency(locale: 'eu').format(123456)); // 123.456,00 EUR
print(NumberFormat.currency(name: 'EURO').format(123456)); // EURO123,456.00
print(NumberFormat.currency(locale: 'eu', symbol: '?').format(123456)); // 123.456,00 ?
print(NumberFormat.currency(locale: 'eu', decimalDigits: 3).format(123456)); // 123.456,000 EUR
print(NumberFormat.currency(locale: 'eu', customPattern: '\u00a4 #,##.#').format(123456)); // EUR 12.34.56,00
Reference & More information: https://www.woolha.com/tutorials/dart-formatting-currency-with-numberformat#supported-locales
NumberFormat Class Dart API: https://api.flutter.dev/flutter/intl/NumberFormat-class.html
In for loop you can try:
Text('Index ${i}'), //Index 0
Format with operation:
Text('Total: \$${price * quantity}'), //$20
With Decimal point:
Text('\$${cart.totalAmount.toStringAsFixed(2)}'), //2.34
Using intl package,
double number = 1234;
String output = NumberFormat.decimalPattern().format(number); // 1,234
There is a Flutter package that allows you to format text input with predefined patterns.
First add the following line to the Dart dependencies: pubspec.yaml file:
pattern_formatter: ^1.0.2```
then import it in your dart code
import 'package:pattern_formatter/pattern_formatter.dart';
Example: Thousand group
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
ThousandsFormatter()
],
)
Decimal Number
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
ThousandsFormatter(allowFraction: true)
],
)
Card number grouping
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
CreditCardFormatter(),
],
)
Date format
TextField(
keyboardType: TextInputType.number,
inputFormatters: [
DateInputFormatter(),
],
)
Using the intl package will limit you to format numbers without decimals. You can make it easy with a function for counting positions and add the thousands separator where it's needed.
String numf(String n) {
var numArr = n.split('');
String revStr = "";
int thousands = 0;
for (var i = numArr.length - 1; i >= 0; i--) {
if (numArr[i].toString() == ".") {
thousands = 0;
} else {
thousands++;
}
revStr = revStr + numArr[i].toString();
if (thousands == 3 && i > 0) {
thousands = 0;
revStr = revStr + ',';
}
}
return revStr.split('').reversed.join('');
}
I've run into an issue with the TabularAdapter in the TraitsUI package...
I've been trying to figure this out on my own for much too long now, so I wanted to ask the experts here for some friendly advise :)
I'm going to add a piece of my program that illustrates my problem(s), and I'm hoping someone can look it over and say 'Ah Ha!...Here's your problem' (my fingers are crossed).
Basically, I can use the TabularAdapter to produce a table editor into an array of dtypes, and it works just fine except:
1) whenever I change the # of elements (identified as 'Number of fractures:'), the array gets resized, but the table doesn't reflect the change until after I click on one of the elements. What I'd like to happen is that the # of rows (fractures) changes after I release the # of fractures slider. Is this doable?
2) The second issue I have is that if the array gets resized before it's displayed by .configure_traits() (by the notifier when Number_of_fractures gets modified), I can shrink the size of the array, but I can't increase it over the new size.
2b) I thought I'd found a way to have the table editor display the full array even when it's increased over the 5 set in the code (just before calling .trait_configure()), but I was fooled :( I tried adding another Group() in front of the vertical_fracture_group so the table wasn't the first thing to display. This more closely emulates my entire program. When I did this, I was locked into the new smaller size of the array, and I could no longer increase its size to my maximum of 15. I'm modifying the code to reflect this issue.
Here's my sample code:
# -*- coding: utf-8 -*-
"""
This is a first shot at developing a ****** User Interface using Canopy by
Enthought. Canopy is a distribution of the Python language which has a lot of
scientific and engineering features 'built-in'.
"""
#-- Imports --------------------------------------------------------------------
from traitsui.api import TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import zeros, dtype
from traits.api import HasTraits, Range
from traitsui.api import View, Group, Item
#-- FileDialogDemo Class -------------------------------------------------------
max_cracks = 15 #maximum number of Fracs/cracks to allow
class VertFractureAdapter(TabularAdapter):
columns = [('Frac #',0), ('X Cen',1), ('Y Cen',2), ('Z Cen',3),
('Horiz',4), ('Vert',5), ('Angle',6)]
class SetupDialog ( HasTraits ):
Number_Of_Fractures = Range(1, max_cracks) # line 277
vertical_frac_dtype = dtype([('Fracture', 'int'), ('x', 'float'), ('y', 'float'),
('z', 'float'), ('Horiz Length', 'float'), ('Vert Length', 'float')
, ('z-axis Rotation, degrees', 'float')])
vertical_frac_array = zeros((max_cracks), dtype=vertical_frac_dtype)
vertical_fracture_group = Group(
Item(name = 'vertical_frac_array',
show_label = False,
editor = TabularEditor(adapter = VertFractureAdapter()),
width = 0.5,
height = 0.5,
)
)
#-- THIS is the actual 'View' that gets put on the screen
view = View(
#Note: When as this group 'displays' before the one with the Table, I'm 'locked' into my new maximum table display size of 8 (not my original/desired maximum of 15)
Group(
Item( name = 'Number_Of_Fractures'),
),
#Note: If I place this Group() first, my table is free to grow to it's maximum of 15
Group(
Item( name = 'Number_Of_Fractures'),
vertical_fracture_group,
),
width = 0.60,
height = 0.50,
title = '****** Setup',
resizable=True,
)
#-- Traits Event Handlers --------------------------------------------------
def _Number_Of_Fractures_changed(self):
""" Handles resizing arrays if/when the number of Fractures is changed"""
print "I've changed the # of Fractures to " + repr(self.Number_Of_Fractures)
#if not self.user_StartingUp:
self.vertical_frac_array.resize(self.Number_Of_Fractures, refcheck=False)
for crk in range(self.Number_Of_Fractures):
self.vertical_frac_array[crk]['Fracture'] = crk+1
self.vertical_frac_array[crk]['x'] = crk
self.vertical_frac_array[crk]['y'] = crk
self.vertical_frac_array[crk]['z'] = crk
# Run the program (if invoked from the command line):
if __name__ == '__main__':
# Create the dialog:
fileDialog = SetupDialog()
fileDialog.configure_traits()
fileDialog.Number_Of_Fractures = 8
In my discussion with Chris below, he made some suggestions that so far haven't worked for me :( Following is my 'current' version of this test code so Chris (or anyone else who wishes to chime in) can see if I'm making some glaring error.
# -*- coding: utf-8 -*-
"""
This is a first shot at developing a ****** User Interface using Canopy by
Enthought. Canopy is a distribution of the Python language which has a lot of
scientific and engineering features 'built-in'.
"""
#-- Imports --------------------------------------------------------------------
from traitsui.api import TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import zeros, dtype
from traits.api import HasTraits, Range, Array, List
from traitsui.api import View, Group, Item
#-- FileDialogDemo Class -------------------------------------------------------
max_cracks = 15 #maximum number of Fracs/cracks to allow
class VertFractureAdapter(TabularAdapter):
columns = [('Frac #',0), ('X Cen',1), ('Y Cen',2), ('Z Cen',3),
('Horiz',4), ('Vert',5), ('Angle',6)]
even_bg_color = 0xf4f4f4 # very light gray
class SetupDialog ( HasTraits ):
Number_Of_Fractures = Range(1, max_cracks) # line 277
dummy = Range(1, max_cracks)
vertical_frac_dtype = dtype([('Fracture', 'int'), ('x', 'float'), ('y', 'float'),
('z', 'float'), ('Horiz Length', 'float'), ('Vert Length', 'float')
, ('z-axis Rotation, degrees', 'float')])
vertical_frac_array = Array(dtype=vertical_frac_dtype)
vertical_fracture_group = Group(
Item(name = 'vertical_frac_array',
show_label = False,
editor = TabularEditor(adapter = VertFractureAdapter()),
width = 0.5,
height = 0.5,
)
)
#-- THIS is the actual 'View' that gets put on the screen
view = View(
Group(
Item( name = 'dummy'),
),
Group(
Item( name = 'Number_Of_Fractures'),
vertical_fracture_group,
),
width = 0.60,
height = 0.50,
title = '****** Setup',
resizable=True,
)
#-- Traits Event Handlers --------------------------------------------------
def _Number_Of_Fractures_changed(self, old, new):
""" Handles resizing arrays if/when the number of Fractures is changed"""
print "I've changed the # of Fractures to " + repr(self.Number_Of_Fractures)
vfa = self.vertical_frac_array
vfa.resize(self.Number_Of_Fractures, refcheck=False)
for crk in range(self.Number_Of_Fractures):
vfa[crk]['Fracture'] = crk+1
vfa[crk]['x'] = crk
vfa[crk]['y'] = crk
vfa[crk]['z'] = crk
self.vertical_frac_array = vfa
# Run the program (if invoked from the command line):
if __name__ == '__main__':
# Create the dialog:
fileDialog = SetupDialog()
# put the actual dialog up...if I put it up 'first' and then resize the array, I seem to get my full range back :)
fileDialog.configure_traits()
#fileDialog.Number_Of_Fractures = 8
There are two details of the code that are causing the problems you describe. First, vertical_frac_array is not a trait, so the tabular editor cannot monitor it for changes. Hence, the table only refreshes when you manually interact with it. Second, traits does not monitor the contents of an array for changes, but rather the identity of the array. So, resizing and assigning values into the array will not be detected.
One way to fix this is to first make vertical_frac_array and Array trait. E.g. vertical_frac_array = Array(dtype=vertical_frac_dtype). Then, inside of _Number_Of_Fractures_changed, do not resize the vertical_frac_array and modify it in-place. Instead, copy vertical_frac_array, resize it, modify the contents, and then reassign the manipulated copy back to vertical_frac_array. This way the table will see that the identity of the array has changed and will refresh the view.
Another option is to make vertical_frac_array a List instead of an Array. This avoids the copy-and-reassign trick above because traits does monitor the content of lists.
Edit
My solution is below. Instead of resizing the vertical_frac_array whenever Number_Of_Fractures changes, I instead recreate the array. I also provide a default value for vertical_frac_array via the _vertical_frac_array_default method. (I removed from unnecessary code in the view as well.)
# -*- coding: utf-8 -*-
"""
This is a first shot at developing a ****** User Interface using Canopy by
Enthought. Canopy is a distribution of the Python language which has a lot of
scientific and engineering features 'built-in'.
"""
#-- Imports --------------------------------------------------------------------
from traitsui.api import TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import dtype, zeros
from traits.api import HasTraits, Range, Array
from traitsui.api import View, Item
#-- FileDialogDemo Class -------------------------------------------------------
max_cracks = 15 #maximum number of Fracs/cracks to allow
vertical_frac_dtype = dtype([('Fracture', 'int'), ('x', 'float'), ('y', 'float'),
('z', 'float'), ('Horiz Length', 'float'), ('Vert Length', 'float')
, ('z-axis Rotation, degrees', 'float')])
class VertFractureAdapter(TabularAdapter):
columns = [('Frac #',0), ('X Cen',1), ('Y Cen',2), ('Z Cen',3),
('Horiz',4), ('Vert',5), ('Angle',6)]
class SetupDialog ( HasTraits ):
Number_Of_Fractures = Range(1, max_cracks) # line 277
vertical_frac_array = Array(dtype=vertical_frac_dtype)
view = View(
Item('Number_Of_Fractures'),
Item(
'vertical_frac_array',
show_label=False,
editor=TabularEditor(
adapter=VertFractureAdapter(),
),
width=0.5,
height=0.5,
),
width=0.60,
height=0.50,
title='****** Setup',
resizable=True,
)
#-- Traits Defaults -------------------------------------------------------
def _vertical_frac_array_default(self):
""" Creates the default value of the `vertical_frac_array`. """
return self._calculate_frac_array()
#-- Traits Event Handlers -------------------------------------------------
def _Number_Of_Fractures_changed(self):
""" Update `vertical_frac_array` when `Number_Of_Fractures` changes """
print "I've changed the # of Fractures to " + repr(self.Number_Of_Fractures)
#if not self.user_StartingUp:
self.vertical_frac_array = self._calculate_frac_array()
#-- Private Interface -----------------------------------------------------
def _calculate_frac_array(self):
arr = zeros(self.Number_Of_Fractures, dtype=vertical_frac_dtype)
for crk in range(self.Number_Of_Fractures):
arr[crk]['Fracture'] = crk+1
arr[crk]['x'] = crk
arr[crk]['y'] = crk
arr[crk]['z'] = crk
return arr
# Run the program (if invoked from the command line):
if __name__ == '__main__':
# Create the dialog:
fileDialog = SetupDialog()
fileDialog.configure_traits()