1# ------------------------------------------------------------------------------ 2# 3# Copyright (c) 2012, Enthought, Inc. 4# All rights reserved. 5# 6# This software is provided without warranty under the terms of the BSD 7# license included in LICENSE.txt and may be redistributed only 8# under the conditions described in the aforementioned license. The license 9# is also available online at http://www.enthought.com/licenses/BSD.txt 10# 11# Author: Pietro Berkes 12# Date: Feb 2012 13# 14# ------------------------------------------------------------------------------ 15 16""" 17Test the creation and layout of labels. 18""" 19import unittest 20 21from traits.has_traits import HasTraits 22from traits.trait_types import Bool, Str 23from traitsui.view import View 24from traitsui.item import Item 25from traitsui.group import VGroup, HGroup 26 27from traitsui.tests._tools import ( 28 BaseTestMixin, 29 create_ui, 30 is_control_enabled, 31 is_qt, 32 requires_toolkit, 33 reraise_exceptions, 34 ToolkitName, 35) 36 37 38_DIALOG_WIDTH = 500 39 40 41class ShowRightLabelsDialog(HasTraits): 42 """ Dialog with labels on the left/right to test the label text. 43 """ 44 45 bool_item = Bool(True) 46 47 traits_view = View( 48 VGroup( 49 VGroup(Item("bool_item"), show_left=False), 50 VGroup(Item("bool_item"), show_left=True), 51 ) 52 ) 53 54 55class HResizeTestDialog(HasTraits): 56 """ Dialog with checkbox and text elements and labels on the right. 57 We test the separation between element and label in HGroups. 58 """ 59 60 bool_item = Bool(True) 61 txt_item = Str() 62 63 traits_view = View( 64 VGroup( 65 HGroup(Item("bool_item", springy=True), show_left=False), 66 VGroup(Item("txt_item", resizable=True), show_left=False), 67 ), 68 width=_DIALOG_WIDTH, 69 height=100, 70 resizable=True, 71 ) 72 73 74class VResizeTestDialog(HasTraits): 75 """ Dialog with checkbox and text elements and labels on the right. 76 We test the separation between element and label in VGroups. 77 """ 78 79 bool_item = Bool(True) 80 txt_item = Str() 81 82 traits_view = View( 83 VGroup( 84 VGroup(Item("bool_item", resizable=True), show_left=False), 85 VGroup(Item("txt_item", resizable=True), show_left=False), 86 ), 87 width=_DIALOG_WIDTH, 88 height=100, 89 resizable=True, 90 ) 91 92 93class NoLabelResizeTestDialog(HasTraits): 94 """ Test the combination show_label=False, show_left=False. 95 """ 96 97 bool_item = Bool(True) 98 99 traits_view = View( 100 VGroup( 101 Item("bool_item", resizable=True, show_label=False), 102 show_left=False, 103 ), 104 resizable=True, 105 ) 106 107 108class EnableWhenDialog(HasTraits): 109 """ Test labels for enable when. """ 110 111 bool_item = Bool(True) 112 113 labelled_item = Str("test") 114 115 unlabelled_item = Str("test") 116 117 traits_view = View( 118 VGroup( 119 Item("bool_item"), 120 Item("labelled_item", enabled_when="bool_item"), 121 Item( 122 "unlabelled_item", enabled_when="bool_item", show_label=False 123 ), 124 ), 125 resizable=True, 126 ) 127 128 129class TestLabels(BaseTestMixin, unittest.TestCase): 130 131 def setUp(self): 132 BaseTestMixin.setUp(self) 133 134 def tearDown(self): 135 BaseTestMixin.tearDown(self) 136 137 @requires_toolkit([ToolkitName.qt]) 138 def test_qt_show_labels_right_without_colon(self): 139 # Behavior: traitsui should not append a colon ':' to labels 140 # that are shown to the *right* of the corresponding elements 141 142 from pyface import qt 143 dialog = ShowRightLabelsDialog() 144 with reraise_exceptions(), \ 145 create_ui(dialog) as ui: 146 147 # get reference to label objects 148 labels = ui.control.findChildren(qt.QtGui.QLabel) 149 150 # the first is shown to the right, so no colon 151 self.assertFalse(labels[0].text().endswith(":")) 152 153 # the second is shown to the right, it should have a colon 154 self.assertTrue(labels[1].text().endswith(":")) 155 156 def _test_qt_labels_right_resizing(self, dialog_class): 157 # Bug: In the Qt backend, resizing a checkbox element with a label on 158 # the right resizes the checkbox, even though it cannot be. 159 # The final effect is that the label remains attached to the right 160 # margin, with a big gap between it and the checkbox. In this case, the 161 # label should be made resizable instead. 162 # On the other hand, a text element should keep the current behavior 163 # and resize. 164 165 from pyface import qt 166 167 with reraise_exceptions(), \ 168 create_ui(dialog_class()) as ui: 169 170 # all labels 171 labels = ui.control.findChildren(qt.QtGui.QLabel) 172 173 # the checkbox and its label should be close to one another; the 174 # size of the checkbox should be small 175 checkbox_label = labels[0] 176 checkbox = ui.control.findChild(qt.QtGui.QCheckBox) 177 178 # horizontal space between checkbox and label should be small 179 h_space = checkbox_label.x() - checkbox.x() 180 self.assertLess(h_space, 100) 181 # and the checkbox size should also be small 182 self.assertLess(checkbox.width(), 100) 183 184 # the text item and its label should be close to one another; the 185 # size of the text item should be large 186 text_label = labels[0] 187 text = ui.control.findChild(qt.QtGui.QLineEdit) 188 189 # horizontal space between text and label should be small 190 h_space = text_label.x() - text.x() 191 self.assertLess(h_space, 100) 192 # and the text item size should be large 193 self.assertGreater(text.width(), _DIALOG_WIDTH - 200) 194 195 # the size of the window should still be 500 196 self.assertEqual(ui.control.width(), _DIALOG_WIDTH) 197 198 @requires_toolkit([ToolkitName.qt]) 199 def test_qt_labels_right_resizing_vertical(self): 200 self._test_qt_labels_right_resizing(VResizeTestDialog) 201 202 @requires_toolkit([ToolkitName.qt]) 203 def test_qt_labels_right_resizing_horizontal(self): 204 self._test_qt_labels_right_resizing(HResizeTestDialog) 205 206 @requires_toolkit([ToolkitName.qt, ToolkitName.wx]) 207 def test_labels_enabled_when(self): 208 # Behaviour: label should enable/disable along with editor 209 210 dialog = EnableWhenDialog() 211 with reraise_exceptions(), \ 212 create_ui(dialog) as ui: 213 214 labelled_editor = ui.get_editors("labelled_item")[0] 215 216 if is_qt(): 217 unlabelled_editor = ui.get_editors("unlabelled_item")[0] 218 self.assertIsNone(unlabelled_editor.label_control) 219 220 self.assertTrue(is_control_enabled(labelled_editor.label_control)) 221 222 dialog.bool_item = False 223 224 self.assertFalse(is_control_enabled(labelled_editor.label_control)) 225 226 dialog.bool_item = True 227 228 229@requires_toolkit([ToolkitName.qt, ToolkitName.wx]) 230class TestAnyToolkit(BaseTestMixin, unittest.TestCase): 231 """ Toolkit-agnostic tests for labels with different orientations.""" 232 233 def setUp(self): 234 BaseTestMixin.setUp(self) 235 236 def tearDown(self): 237 BaseTestMixin.tearDown(self) 238 239 def test_group_show_right_labels(self): 240 with reraise_exceptions(), \ 241 create_ui(ShowRightLabelsDialog()): 242 pass 243 244 def test_horizontal_resizable_and_labels(self): 245 with reraise_exceptions(), \ 246 create_ui(HResizeTestDialog()): 247 pass 248 249 def test_all_resizable_with_labels(self): 250 with reraise_exceptions(), \ 251 create_ui(VResizeTestDialog()): 252 pass 253 254 def test_show_right_with_no_label(self): 255 # Bug: If one set show_left=False, show_label=False on a non-resizable 256 # item like a checkbox, the Qt backend tried to set the label's size 257 # policy and failed because label=None. 258 with reraise_exceptions(), \ 259 create_ui(NoLabelResizeTestDialog()): 260 pass 261 262 def test_enable_when_flag(self): 263 with reraise_exceptions(), \ 264 create_ui(EnableWhenDialog()): 265 pass 266 267 268if __name__ == "__main__": 269 # Execute from command line for manual testing 270 vw = HResizeTestDialog() 271 vw.configure_traits() 272