TraitsUI - Joining views - python

Reading the documentation about applying the MVC pattern with TraitsUI, I read the example MVC_demo.py. Now, I'm wondering how to manage multiple "MVC".
I want to write some "includeallMVCs.py" and to have something like:
import MyViewController1, MyViewController2, MyViewController2
class IncludeallMVCs(HasTraits):
view = Include(MyViewController1, MyViewController2, MyViewController3)
Where MyViewController, MyViewController, MyViewController are classes like the MVC_demo sample.
So, the idea is to separate differents views with their controllers, and then "join" all of them in only one "generic" view.

Searching in the examples I found this one: Dynamic Forms Using Instances
Then I modified it to separate an AdultHandler. In this example I use the salary variable to be controlled by AdultHandler.
File: adult.py
from traitsui.api import Handler
class AdultHandler(Handler):
def object_salary_changed (self, info):
if (info.object.salary >= 20000):
print "Good Salary!"
else:
print "Bad Salary"
File: adult_model.py
from adult import AdultHandler
class AdultSpec ( HasTraits ):
""" Trait list for adults (assigned to 'misc' for a Person when age >= 18).
"""
marital_status = Enum( 'single', 'married', 'divorced', 'widowed' )
registered_voter = Bool
military_service = Bool
salary = Int
traits_view = View(
'marital_status',
'registered_voter',
'military_service',
'salary',
handler = AdultHandler()
)
if __name__ == '__main__':
a = AdultSpec()
a.configure_traits()
File: main.py
from adult_model import AdultSpec
class Person ( HasTraits ):
""" Demo class for demonstrating dynamic interface restructuring.
"""
datainput = Instance( AdultSpec )
# Interface for attributes that depend on the value of 'age':
spec_group = Group(
Group(
Item( name = 'datainput', style = 'custom' ),
show_labels = False
),
label = 'Additional Info',
show_border = True
)
# A simple View is enough as long as the right handler is specified:
view = View(
Group(
spec_group
),
title = 'Using MVC',
buttons = [ 'OK' ],
resizable = True,
width = 300
)
# Create the demo:
demo = Person( datainput = AdultSpec() )
# Run the demo (if invoked from the command line):
if __name__ == '__main__':
demo.configure_traits()

Related

Vertical scrollbar in FLET app, does not appear

I am building a FLET app, but sometimes I have a datatable which is too large for the frame it is in. For the row I have a scrollbar appearing, but for the column I just don't seem to get it working.
In this code a scrollbar simply does not appear.
import pandas as pd
pd.options.display.max_columns = 100
from services.bag import PCHN
from utils.convertors import dataframe_to_datatable
import flet as ft
def main(page: ft.page):
def bag_service(e):
pc = '9351BP' if postal_code_field.value == '' else postal_code_field.value
hn = '1' if house_number_field.value == '' else house_number_field.value
address = PCHN(pc,
hn).result
bag_container[0] = dataframe_to_datatable(address)
page.update() # This is not updating my bag_table in place though. It stays static as it is.
# define form fields
postal_code_field = ft.TextField(label='Postal code')
house_number_field = ft.TextField(label='House number')
submit_button = ft.ElevatedButton(text='Submit', on_click=bag_service)
# fields for the right column
address = PCHN('9351BP', '1').result
bag_table = dataframe_to_datatable(address)
bag_container = [bag_table]
# design layout
# 1 column to the left as a frame and one to the right with two rows
horizontal_divider = ft.Row
left_column = ft.Column
right_column = ft.Column
# fill the design
page.add(
horizontal_divider(
[left_column(
[postal_code_field,
house_number_field,
submit_button
]
),
right_column(
[
ft.Container(
ft.Row(
bag_container,
scroll='always'
),
bgcolor=ft.colors.BLACK,
width=800,)
],scroll='always'
)
]
)
)
if __name__ == '__main__':
ft.app(target=main,
view=ft.WEB_BROWSER,
port=666
)
I am lost as to what could be the case here. Any help would be much appreciated.

Flask Admin , not able to put filter and can not set search column

I have went through other answers but none of them seems to answer this question , I have cloned sandman2 which does not have column filter and column searchable option in admin dashboard , below is the ModelView
from flask_admin.contrib.sqla import ModelView
class CustomAdminView(ModelView): # pylint: disable=no-init
"""Define custom templates for each view."""
list_template = 'list.html'
create_template = 'create.html'
edit_template = 'edit.html'
column_display_pk = True
ModelView.can_export = True
ModelView.can_delete = False
ModelView.can_view_details = True
ModelView.can_set_page_size = True
ModelView.can_create = False
ModelView.page_size = 500
And I am calling this in app.py
def register_model(cls, admin=None):
"""Register *cls* to be included in the API service
:param cls: Class deriving from :class:`sandman2.models.Model`
"""
cls.__url__ = '/{}'.format(cls.__name__.lower())
service_class = type(
cls.__name__ + 'Service',
(Service,),
{
'__model__': cls,
})
# inspect primary key
cols = list(cls().__table__.primary_key.columns)
# composite keys not supported (yet)
primary_key_type = 'string'
if len(cols) == 1:
col_type = cols[0].type
# types defined at http://flask.pocoo.org/docs/0.10/api/#url-route-registrations
if isinstance(col_type, sqltypes.String):
primary_key_type = 'string'
elif isinstance(col_type, sqltypes.Integer):
primary_key_type = 'int'
elif isinstance(col_type, sqltypes.Numeric):
primary_key_type = 'float'
# registration
register_service(service_class, primary_key_type)
if admin is not None:
columns = (c.name for c in (list(cls().__table__.columns)) if not c.primary_key)
cv = CustomAdminView(cls, db.session)
cv.column_filters = columns
cv.column_searchable_list = list(columns)
admin.add_view(cv)
Still no luck , no filter option on the admin neither the filter option.

Switchable Radio Buttons (editing a command)

I'm a bit stuck on how to write the correct syntax for editing a command.
way down in my radioOn and radioOff commands, I would like the enable / disable checkbox to enable or disable the radio buttons.
from functools import partial
import maya.cmds as cmds
def one ():
print '1'
def two ():
print '2'
winID = 'xx'
if cmds.window(winID, exists=True):
cmds.deleteUI(winID)
window = cmds.window(winID, sizeable = False, title="Resolution Switcher", widthHeight=(300, 100) )
cmds.columnLayout( )
cmds.text (label = '')
cmds.text (label = '')
cmds.checkBoxGrp( cat = (1,'left', 20), ncb = 1, l1=' DISABLE', offCommand = partial(radioOn, a), onCommand = partial(radioOff, a) )
a = cmds.radioButtonGrp( cat = [(1,'left', 90),(2, 'left', 100)], numberOfRadioButtons=2, on1 = 'one ()' , on2 = 'two ()' )
cmds.text (label = '')
def radioOff (a, *args):
print 'radios off'
a(ed=True, enable=False)
def radioOn (a, *args):
print 'radios on'
a(ed=True, enable=False)
cmds.showWindow( window )
I've tried to get an idea from examples such as the one shown here, but
but when I put down cmds.radioButtonGrp(a, ed=True, enable=False) it just keeps creating new radio buttons, not unlike what was shown in the example with float fields.
bottom line is - I just want the radio buttons to be greyed out and disabled whenever I hit the checkbox. Speaking of which - Is it possible to grey out the radio buttons the same way float fields can? I noticed that disabling them only makes them unclickable - but not greyed out.
Thank you in advance.
from functools import partial
import maya.cmds as cmds
def one (*args):
print '1'
def two (*args):
print '2'
def radioSwitch (a, state, *args):
if state:
cmds.radioButtonGrp(a, e=True, enable=False)
else:
cmds.radioButtonGrp(a, e=True, enable=True)
winID = 'xx'
if cmds.window(winID, exists=True):
cmds.deleteUI(winID)
window = cmds.window(winID, sizeable = False, title="Resolution Switcher", widthHeight=(300, 100) )
cmds.columnLayout( )
cmds.text (label = '')
cmds.text (label = '')
cb_disable = cmds.checkBoxGrp( cat = (1,'left', 20), ncb = 1, l1=' DISABLE', offCommand = "" , onCommand = "" )
a = cmds.radioButtonGrp( cat = [(1,'left', 90),(2, 'left', 100)], enable=True, numberOfRadioButtons=2, on1 = one , on2 = two )
cmds.checkBoxGrp(cb_disable, e=1, offCommand = partial(radioSwitch, a, False))
cmds.checkBoxGrp(cb_disable, e=1, onCommand = partial(radioSwitch, a, True))
cmds.text (label = '')
cmds.showWindow( window )

Blender 3D Add-on Script loading failed

Heading
I made add-on script.
However loading fail in blender UI.
Error message is '_RestrictContext' object has no attribute 'scene' .
But this script is very well run in blender of Text Editor.
Why don't load this add-on?
bl_info = {
"name": "Add Cube",
"author": "jsh",
"version": (1, 0),
"blender": (2, 68, 0),
"location": "View3D > Tool Shelf > Text make",
"description": "Adds a new Mesh Object",
"warning": "",
"wiki_url": "",
"tracker_url": "http://togetherall.infomaster.co.kr",
"category": "Object"}
import bpy
from bpy.props import *
#
# Store properties in the active scene
#
def initSceneProperties(scn):
bpy.types.Scene.MyInt = IntProperty(
name = "Integer",
description = "Enter an integer")
scn['MyInt'] = 17
bpy.types.Scene.MyFloat = FloatProperty(
name = "Float",
description = "Enter a float",
default = 33.33,
min = -100,
max = 100)
bpy.types.Scene.MyBool = BoolProperty(
name = "Boolean",
description = "True or False?")
scn['MyBool'] = True
bpy.types.Scene.MyEnum = EnumProperty(
items = [('Eine', 'Un', 'One'),
('Zwei', 'Deux', 'Two'),
('Drei', 'Trois', 'Three')],
name = "Ziffer")
scn['MyEnum'] = 2
bpy.types.Scene.MyString = StringProperty(
name = "String2")
scn['MyString'] = "Lorem ipsum dolor sit amet"
return
initSceneProperties(bpy.context.scene)
#
# Menu in UI region
#
class UIPanel(bpy.types.Panel):
bl_label = "Make Text"
bl_space_type = "VIEW_3D"
#bl_region_type = "UI"
bl_region_type = "TOOL_PROPS"
def draw(self, context):
layout = self.layout
scn = context.scene
layout.prop(scn, 'MyInt', icon='BLENDER', toggle=True)
layout.prop(scn, 'MyFloat')
layout.prop(scn, 'MyBool')
layout.prop(scn, 'MyEnum')
layout.prop(scn, 'MyString')
layout.operator("idname_must.be_all_lowercase_and_contain_one_dot")
#
# The button prints the values of the properites in the console.
#
class OBJECT_OT_PrintPropsButton(bpy.types.Operator):
bl_idname = "idname_must.be_all_lowercase_and_contain_one_dot"
bl_label = "make"
def execute(self, context):
bpy.ops.mesh.primitive_cube_add()
return{'FINISHED'}
def printProp(label, key, scn):
try:
val = scn[key]
except:
val = 'Undefined'
#print("%s %s" % (key, val))
return val
def register():
bpy.utils.register_class(UIPanel)
bpy.utils.register_class(OBJECT_OT_PrintPropsButton)
def unregister():
bpy.utils.unregister_class(UIPanel)
bpy.utils.unregister_class(OBJECT_OT_PrintPropsButton)
if __name__ == "__main__":
register()
Blender uses a so called RestrictContext during the register / unregsiter phase of a plugin. This means, you're not allowed to do certain operations on the context because the content might not be ready yet.
In your case, you're doing initSceneProperties(bpy.context.scene) in the global module scope, which means it will be executed immediately after that module is being loaded. Move that initialization code for example in your operator's execute() method and do it when the operator is first run, or any other place where it makes sense (as late as possible, as early as necessary).
See the docs on RestrictContext for an example on how to do this.

How do I get close event to work in wxPython using AUIManager?

How would I add another event to the pane created in our GUI manager class (below). I want to detect when the x button closes the pane. I've tried using the same format as wx.EVT_MENU for wx.EVT_CLOSE but it didn't work.
def popup_panel(self, p):
"""
Add a panel object to the AUI manager
:param p: panel object to add to the AUI manager
:return: ID of the event associated with the new panel [int]
"""
ID = wx.NewId()
self.panels[str(ID)] = p
self.graph_num += 1
if p.window_caption.split()[0] in NOT_SO_GRAPH_LIST:
windowcaption = p.window_caption
else:
windowcaption = 'Graph'#p.window_caption
windowname = p.window_name
# Append nummber
captions = self._get_plotpanel_captions()
while (1):
caption = windowcaption + '%s'% str(self.graph_num)
if caption not in captions:
break
self.graph_num += 1
# protection from forever-loop: max num = 1000
if self.graph_num > 1000:
break
if p.window_caption.split()[0] not in NOT_SO_GRAPH_LIST:
p.window_caption = caption
#p.window_caption = windowcaption+ str(self.graph_num)
p.window_name = windowname + str(self.graph_num)
style1 = self.__gui_style & GUIFRAME.FIXED_PANEL
style2 = self.__gui_style & GUIFRAME.FLOATING_PANEL
if style1 == GUIFRAME.FIXED_PANEL:
self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
Name(p.window_name).
Caption(p.window_caption).
Position(10).
Floatable().
Right().
Dock().
MinimizeButton().
Resizable(True).
# Use a large best size to make sure the AUI
# manager takes all the available space
BestSize(wx.Size(PLOPANEL_WIDTH,
PLOPANEL_HEIGTH)))
self._popup_fixed_panel(p)
elif style2 == GUIFRAME.FLOATING_PANEL:
self._mgr.AddPane(p, wx.aui.AuiPaneInfo().
Name(p.window_name).Caption(p.window_caption).
MinimizeButton().
Resizable(True).
# Use a large best size to make sure the AUI
# manager takes all the available space
BestSize(wx.Size(PLOPANEL_WIDTH,
PLOPANEL_HEIGTH)))
self._popup_floating_panel(p)
# Register for showing/hiding the panel
wx.EVT_MENU(self, ID, self.on_view)
if p not in self.plot_panels.values() and p.group_id != None:
self.plot_panels[ID] = p
if len(self.plot_panels) == 1:
self.panel_on_focus = p
self.set_panel_on_focus(None)
if self._data_panel is not None and \
self._plotting_plugin is not None:
ind = self._data_panel.cb_plotpanel.FindString('None')
if ind != wx.NOT_FOUND:
self._data_panel.cb_plotpanel.Delete(ind)
if caption not in self._data_panel.cb_plotpanel.GetItems():
self._data_panel.cb_plotpanel.Append(str(caption), p)
return ID
I want to be able to pick up the event in the plotting child class.
def create_panel_helper(self, new_panel, data, group_id, title=None):
"""
"""
## Set group ID if available
## Assign data properties to the new create panel
new_panel.set_manager(self)
new_panel.group_id = group_id
if group_id not in data.list_group_id:
data.list_group_id.append(group_id)
if title is None:
title = data.title
new_panel.window_caption = title
new_panel.window_name = data.title
event_id = self.parent.popup_panel(new_panel)
#remove the default item in the menu
if len(self.plot_panels) == 0:
pos = self.menu.FindItem(DEFAULT_MENU_ITEM_LABEL)
if pos != -1:
self.menu.Delete(DEFAULT_MENU_ITEM_ID)
# Set UID to allow us to reference the panel later
new_panel.uid = event_id
# Ship the plottable to its panel
wx.CallAfter(new_panel.plot_data, data)
self.plot_panels[new_panel.group_id] = new_panel
# Set Graph menu and help string
helpString = 'Show/Hide Graph: '
for plot in new_panel.plots.itervalues():
helpString += (' ' + plot.label + ';')
self.menu.AppendCheckItem(event_id, new_panel.window_caption,
helpString)
self.menu.Check(event_id, IS_WIN)
wx.EVT_MENU(self.parent, event_id, self._on_check_menu)
wx.EVT_CLOSE(self.parent, event_id, self._on_close_panel)
wx.EVT_SHOW(new_panel, self._on_show_panel)
Did you try catching wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE or wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSED? I would think that would do what you want. I am assuming you're using wx.aui rather than wx.agw.aui. I suspect the latter is similar though.
EDIT: Oops. I read this wrong. I thought the OP wanted to know about AUINotebook. The event you're probably looking for is wx.aui.EVT_AUI_PANE_CLOSE

Categories

Resources