def _test_tree_node_object_releases_listeners(self, hide_root, nodes=None, trait='bogus_list', expected_listeners=1): """ The TreeEditor should release the listener to the root node's children when it's disposed of. """ with store_exceptions_on_all_threads(): bogus = BogusTreeNodeObject(bogus_list=[BogusTreeNodeObject()]) tree_editor_view = BogusTreeNodeObjectView( bogus=bogus, hide_root=hide_root, nodes=nodes, ) ui = tree_editor_view.edit_traits() # The TreeEditor sets a listener on the bogus object's # children list notifiers_list = bogus.trait(trait)._notifiers(False) self.assertEqual(expected_listeners, len(notifiers_list)) # Manually close the UI press_ok_button(ui) # The listener should be removed after the UI has been closed notifiers_list = bogus.trait(trait)._notifiers(False) self.assertEqual(0, len(notifiers_list))
def test_csv_editor_external_append(self): # Behavior: CSV editor is notified when an element is appended to the # list externally def _wx_get_text_value(ui): txt_ctrl = ui.control.FindWindowByName("text", ui.control) return txt_ctrl.GetValue() def _qt_get_text_value(ui): from pyface import qt txt_ctrl = ui.control.findChild(qt.QtGui.QLineEdit) return txt_ctrl.text() list_of_floats = ListOfFloats(data=[1.0]) csv_view = ListOfFloatsWithCSVEditor(model=list_of_floats) with store_exceptions_on_all_threads(), create_ui(csv_view) as ui: # add element to list, make sure that editor knows about it list_of_floats.data.append(3.14) # get current value from editor if is_current_backend_wx(): value_str = _wx_get_text_value(ui) elif is_current_backend_qt4(): value_str = _qt_get_text_value(ui) expected = csv_list_editor._format_list_str([1.0, 3.14]) self.assertEqual(value_str, expected) press_ok_button(ui)
def _test_tree_node_object_releases_listeners(self, hide_root, nodes=None, trait="bogus_list", expected_listeners=1): """ The TreeEditor should release the listener to the root node's children when it's disposed of. """ bogus = BogusTreeNodeObject(bogus_list=[BogusTreeNodeObject()]) tree_editor_view = BogusTreeNodeObjectView(bogus=bogus, hide_root=hide_root, nodes=nodes) with store_exceptions_on_all_threads(), \ create_ui(tree_editor_view) as ui: # The TreeEditor sets a listener on the bogus object's # children list notifiers_list = bogus.trait(trait)._notifiers(False) self.assertEqual(expected_listeners, len(notifiers_list)) if trait == "name": # fire a label change bogus.name = "Something else" else: # change the children bogus.bogus_list.append(BogusTreeNodeObject()) # Manually close the UI press_ok_button(ui) # The listener should be removed after the UI has been closed notifiers_list = bogus.trait(trait)._notifiers(False) self.assertEqual(0, len(notifiers_list))
def test_selection_listener_disconnected(): """ Check that selection listeners get correctly disconnected """ from pyface.api import GUI from pyface.qt.QtGui import QApplication, QItemSelectionModel from pyface.ui.qt4.util.event_loop_helper import EventLoopHelper from pyface.ui.qt4.util.testing import event_loop obj = ListStrEditorWithSelectedIndex(values=['value1', 'value2']) with store_exceptions_on_all_threads(): qt_app = QApplication.instance() if qt_app is None: qt_app = QApplication([]) helper = EventLoopHelper(gui=GUI(), qt_app=qt_app) # open the UI and run until the dialog is closed ui = obj.edit_traits(view=single_select_item_view) with helper.delete_widget(ui.control): press_ok_button(ui) # now run again and change the selection ui = obj.edit_traits(view=single_select_item_view) with event_loop(): editor = ui.get_editors('values')[0] list_view = editor.list_view mi = editor.model.index(1) list_view.selectionModel().select(mi, QItemSelectionModel.ClearAndSelect) obj.selected = 'value2'
def test_table_editor_select_cells(): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)] ) object_list.selected_cells = [ (object_list.values[5], 'value'), (object_list.values[6], 'other value'), (object_list.values[8], 'value'), ] with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=select_cells_view) editor = ui.get_editors('values')[0] gui.process_events() if is_current_backend_qt4(): selected = editor.selected elif is_current_backend_wx(): selected = editor.selected_cells press_ok_button(ui) gui.process_events() assert selected == [ (object_list.values[5], 'value'), (object_list.values[6], 'other value'), (object_list.values[8], 'value'), ]
def test_progress_column(): from traitsui.extras.progress_column import ProgressColumn progress_view = View( Item( 'values', show_label=False, editor=TableEditor( columns=[ ObjectColumn(name='value'), ProgressColumn(name='other_value'), ], ) ), buttons=['OK'], ) gui = GUI() object_list = ObjectList( values=[ListItem(value=str(i**2)) for i in range(10)] ) with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=progress_view) gui.process_events() press_ok_button(ui) gui.process_events()
def test_table_editor_select_cells(): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)]) object_list.selected_cells = [ (object_list.values[5], "value"), (object_list.values[6], "other value"), (object_list.values[8], "value"), ] with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=select_cells_view) editor = ui.get_editors("values")[0] gui.process_events() if is_current_backend_qt4(): selected = editor.selected elif is_current_backend_wx(): selected = editor.selected_cells press_ok_button(ui) gui.process_events() assert selected == [ (object_list.values[5], "value"), (object_list.values[6], "other value"), (object_list.values[8], "value"), ]
def test_qt_tuple_editor(self): # Behavior: when editing the text of a tuple editor, # value get updated immediately. from pyface import qt val = TupleEditor() with store_exceptions_on_all_threads(), create_ui(val) as ui: # the following is equivalent to clicking in the text control of # the range editor, enter a number, and clicking ok without # defocusing # text element inside the spin control lineedits = ui.control.findChildren(qt.QtGui.QLineEdit) lineedits[0].setFocus() lineedits[0].clear() lineedits[0].insert("4") lineedits[1].setFocus() lineedits[1].clear() lineedits[1].insert("6") # if all went well, the tuple trait has been updated and its value # is 4 self.assertEqual(val.tup, (4, 6)) # press the OK button and close the dialog press_ok_button(ui)
def test_table_editor(): gui = GUI() object_list = ObjectList(values=[ListItem(value=str(i ** 2)) for i in range(10)]) with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=simple_view) gui.process_events() press_ok_button(ui) gui.process_events()
def test_simple_editor_parent_closed(self): obj = NonmodalInstanceEditor() with store_exceptions_on_all_threads(), create_ui(obj) as ui: editor = ui.get_editors("inst")[0] # make the dialog appear editor._button.click() # close the main ui press_ok_button(ui)
def test_simple_editor(self): obj = NonmodalInstanceEditor() with reraise_exceptions(), create_ui(obj) as ui: editor = ui.get_editors("inst")[0] # make the dialog appear editor._button.click() # close the ui dialog press_ok_button(editor._dialog_ui)
def test_table_editor(self): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)]) with store_exceptions_on_all_threads(), \ create_ui(object_list, dict(view=simple_view)) as ui: gui.process_events() press_ok_button(ui) gui.process_events()
def test_table_editor(): gui = GUI() object_list = ObjectList( values=[ListItem(value=str(i**2)) for i in range(10)]) with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=simple_view) gui.process_events() press_ok_button(ui) gui.process_events()
def test_simple_editor_parent_closed(): with store_exceptions_on_all_threads(): obj = NonmodalInstanceEditor() ui = obj.edit_traits() editor = ui.get_editors('inst')[0] # make the dialog appear editor._button.click() # close the main ui press_ok_button(ui)
def test_simple_editor_parent_closed(): with store_exceptions_on_all_threads(): obj = NonmodalInstanceEditor() ui = obj.edit_traits() editor = ui.get_editors("inst")[0] # make the dialog appear editor._button.click() # close the main ui press_ok_button(ui)
def test_filtered_table_editor(self): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)]) with store_exceptions_on_all_threads(), \ create_ui(object_list, dict(view=filtered_view)) as ui: gui.process_events() filter = ui.get_editors("values")[0].filter press_ok_button(ui) gui.process_events() self.assertIsNotNone(filter)
def test_filtered_table_editor(): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)]) with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=filtered_view) gui.process_events() filter = ui.get_editors("values")[0].filter press_ok_button(ui) gui.process_events() assert filter is not None
def test_filtered_table_editor(): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)] ) with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=filtered_view) gui.process_events() filter = ui.get_editors('values')[0].filter press_ok_button(ui) gui.process_events() assert filter is not None
def test_csv_editor_disposal(self): # Bug: CSVListEditor does not un-hook the traits notifications after # its disposal, causing errors when the hooked data is accessed after # the window is closed (Issue #48) list_of_floats = ListOfFloats(data=[1, 2, 3]) csv_view = ListOfFloatsWithCSVEditor(model=list_of_floats) try: with store_exceptions_on_all_threads(), create_ui(csv_view) as ui: press_ok_button(ui) # raise an exception if still hooked list_of_floats.data.append(2) except AttributeError: # if all went well, we should not be here self.fail("AttributeError raised")
def test_table_editor_select_column_index(): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)]) object_list.selected_index = 1 with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=select_column_index_view) editor = ui.get_editors("values")[0] gui.process_events() if is_current_backend_qt4(): selected = editor.selected_indices elif is_current_backend_wx(): selected = editor.selected_column_index press_ok_button(ui) gui.process_events() assert selected == 1
def test_table_editor_select_cell(self): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)]) object_list.selected_cell = (object_list.values[5], "value") with store_exceptions_on_all_threads(), \ create_ui(object_list, dict(view=select_cell_view)) as ui: editor = ui.get_editors("values")[0] gui.process_events() if is_current_backend_qt4(): selected = editor.selected elif is_current_backend_wx(): selected = editor.selected_cell press_ok_button(ui) gui.process_events() self.assertEqual(selected, (object_list.values[5], "value"))
def test_wx_text_editing(self): # behavior: when editing the text part of a spin control box, pressing # the OK button should update the value of the HasTraits class # (tests a bug where this fails with an AttributeError) num = NumberWithRangeEditor() with store_exceptions_on_all_threads(), create_ui(num) as ui: # the following is equivalent to setting the text in the text # control, then pressing OK textctrl = ui.control.FindWindowByName("text") textctrl.SetValue("1") # press the OK button and close the dialog press_ok_button(ui) # the number traits should be between 3 and 8 self.assertTrue(3 <= num.number <= 8)
def test_table_editor_select_column_index(): gui = GUI() object_list = ObjectListWithSelection( values=[ListItem(value=str(i**2)) for i in range(10)] ) object_list.selected_index = 1 with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=select_column_index_view) editor = ui.get_editors('values')[0] gui.process_events() if is_current_backend_qt4(): selected = editor.selected_indices elif is_current_backend_wx(): selected = editor.selected_column_index press_ok_button(ui) gui.process_events() assert selected == 1
def test_avoid_slider_feedback(self): # behavior: when editing the text box part of a range editor, the value # should not be adjusted by the slider part of the range editor from pyface import qt num = FloatWithRangeEditor() with store_exceptions_on_all_threads(), create_ui(num) as ui: # the following is equivalent to setting the text in the text # control, then pressing OK lineedit = ui.control.findChild(qt.QtGui.QLineEdit) lineedit.setFocus() lineedit.setText("4") lineedit.editingFinished.emit() # press the OK button and close the dialog press_ok_button(ui) # the number trait should be 4 extactly self.assertEqual(num.number, 4.0)
def test_progress_column(): from traitsui.extras.progress_column import ProgressColumn progress_view = View( Item('values', show_label=False, editor=TableEditor(columns=[ ObjectColumn(name='value'), ProgressColumn(name='other_value'), ], )), buttons=['OK'], ) gui = GUI() object_list = ObjectList( values=[ListItem(value=str(i**2)) for i in range(10)]) with store_exceptions_on_all_threads(): ui = object_list.edit_traits(view=progress_view) gui.process_events() press_ok_button(ui) gui.process_events()
def test_progress_column(self): from traitsui.extras.progress_column import ProgressColumn progress_view = View( Item( "values", show_label=False, editor=TableEditor(columns=[ ObjectColumn(name="value"), ProgressColumn(name="other_value"), ]), ), buttons=["OK"], ) gui = GUI() object_list = ObjectList( values=[ListItem(value=str(i**2)) for i in range(10)]) with store_exceptions_on_all_threads(), \ create_ui(object_list, dict(view=progress_view)) as ui: gui.process_events() press_ok_button(ui) gui.process_events()
def test_wx_list_str_selected_index(): # behavior: when starting up, the with store_exceptions_on_all_threads(): obj = ListStrEditorWithSelectedIndex(values=['value1', 'value2'], selected_index=1) ui = obj.edit_traits(view=single_select_view) # the following is equivalent to setting the text in the text control, # then pressing OK liststrctrl = ui.control.FindWindowByName('listCtrl') selected_1 = get_selected(liststrctrl) obj.selected_index = 0 selected_2 = get_selected(liststrctrl) # press the OK button and close the dialog press_ok_button(ui) # the number traits should be between 3 and 8 assert selected_1 == [1] assert selected_2 == [0]
def test_wx_list_str_multi_selected_index(self): # behavior: when starting up, the obj = ListStrEditorWithSelectedIndex( values=["value1", "value2"], selected_indices=[1] ) with store_exceptions_on_all_threads(), \ create_ui(obj, dict(view=multi_select_view)) as ui: editor = ui.get_editors("values")[0] # the following is equivalent to setting the text in the text # control, then pressing OK selected_1 = get_selected_indices(editor) obj.selected_indices = [0] selected_2 = get_selected_indices(editor) # press the OK button and close the dialog press_ok_button(ui) # the number traits should be between 3 and 8 self.assertEqual(selected_1, [1]) self.assertEqual(selected_2, [0])
def test_wx_spin_control_editing_does_not_update(self): # Bug: when editing the text part of a spin control box, pressing # the OK button does not update the value of the HasTraits class # on Mac OS X # But under wx >= 3.0 this has been resolved import wx if wx.VERSION >= (3, 0): return num = NumberWithSpinnerEditor() with store_exceptions_on_all_threads(), create_ui(num) as ui: # the following is equivalent to clicking in the text control of # the range editor, enter a number, and clicking ok without # defocusing # SpinCtrl object spin = ui.control.FindWindowByName("wxSpinCtrl") spin.SetFocusFromKbd() # on Windows, a wxSpinCtrl does not have children, and we cannot do # the more fine-grained testing below if len(spin.GetChildren()) == 0: spin.SetValueString("4") else: # TextCtrl object of the spin control spintxt = spin.FindWindowByName("text") spintxt.SetValue("4") # press the OK button and close the dialog press_ok_button(ui) # if all went well, the number traits has been updated and its # value is 4 self.assertEqual(num.number, 4)
def test_wx_list_str_selected_index(): # behavior: when starting up, the with store_exceptions_on_all_threads(): obj = ListStrEditorWithSelectedIndex( values=['value1', 'value2'], selected_index=1) ui = obj.edit_traits(view=single_select_view) # the following is equivalent to setting the text in the text control, # then pressing OK liststrctrl = ui.control.FindWindowByName('listCtrl') selected_1 = get_selected(liststrctrl) obj.selected_index = 0 selected_2 = get_selected(liststrctrl) # press the OK button and close the dialog press_ok_button(ui) # the number traits should be between 3 and 8 assert selected_1 == [1] assert selected_2 == [0]
def test_qt_spin_control_editing(self): # Behavior: when editing the text part of a spin control box, pressing # the OK button updates the value of the HasTraits class from pyface import qt num = NumberWithSpinnerEditor() with store_exceptions_on_all_threads(), create_ui(num) as ui: # the following is equivalent to clicking in the text control of # the range editor, enter a number, and clicking ok without # defocusing # text element inside the spin control lineedit = ui.control.findChild(qt.QtGui.QLineEdit) lineedit.setFocus() lineedit.setText("4") # press the OK button and close the dialog press_ok_button(ui) # if all went well, the number traits has been updated and its value is # 4 self.assertEqual(num.number, 4)