1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
import pytest
import numpy as np
from echo.core import CallbackProperty
from echo.selection import SelectionCallbackProperty, ChoiceSeparator
from echo.qt.tests.helpers import SKIP_QT_TEST
if SKIP_QT_TEST:
pytest.skip(allow_module_level=True)
from qtpy import QtWidgets
from qtpy.QtCore import Qt
from echo.qt.connect import connect_list_selection
class Example(object):
a = SelectionCallbackProperty(default_index=1)
b = CallbackProperty()
def test_connect_list_selection():
t = Example()
a_prop = getattr(type(t), 'a')
a_prop.set_choices(t, [4, 3.5])
a_prop.set_display_func(t, lambda x: 'value: {0}'.format(x))
list_widget = QtWidgets.QListWidget()
c1 = connect_list_selection(t, 'a', list_widget) # noqa
assert list_widget.item(0).text() == 'value: 4'
assert list_widget.item(1).text() == 'value: 3.5'
assert list_widget.item(0).data(Qt.UserRole).data == 4
assert list_widget.item(1).data(Qt.UserRole).data == 3.5
list_widget.setCurrentItem(list_widget.item(1))
assert t.a == 3.5
list_widget.setCurrentItem(list_widget.item(0))
assert t.a == 4
list_widget.setCurrentItem(list_widget.item(-1))
assert t.a is None
t.a = 3.5
assert len(list_widget.selectedItems()) == 1
assert list_widget.selectedItems()[0] is list_widget.item(1)
t.a = 4
assert len(list_widget.selectedItems()) == 1
assert list_widget.selectedItems()[0] is list_widget.item(0)
with pytest.raises(ValueError) as exc:
t.a = 2
assert exc.value.args[0] == 'value 2 is not in valid choices: [4, 3.5]'
t.a = None
assert len(list_widget.selectedItems()) == 0
# Changing choices should change Qt list_widget box. Let's first try with a case
# in which there is a matching data value in the new list_widget box
t.a = 3.5
assert len(list_widget.selectedItems()) == 1
assert list_widget.selectedItems()[0] is list_widget.item(1)
a_prop.set_choices(t, (4, 5, 3.5))
assert list_widget.count() == 3
assert t.a == 3.5
assert len(list_widget.selectedItems()) == 1
assert list_widget.selectedItems()[0] is list_widget.item(2)
assert list_widget.item(0).text() == 'value: 4'
assert list_widget.item(1).text() == 'value: 5'
assert list_widget.item(2).text() == 'value: 3.5'
assert list_widget.item(0).data(Qt.UserRole).data == 4
assert list_widget.item(1).data(Qt.UserRole).data == 5
assert list_widget.item(2).data(Qt.UserRole).data == 3.5
# Now we change the choices so that there is no matching data - in this case
# the index should change to that given by default_index
a_prop.set_choices(t, (4, 5, 6))
assert t.a == 5
assert len(list_widget.selectedItems()) == 1
assert list_widget.selectedItems()[0] is list_widget.item(1)
assert list_widget.count() == 3
assert list_widget.item(0).text() == 'value: 4'
assert list_widget.item(1).text() == 'value: 5'
assert list_widget.item(2).text() == 'value: 6'
assert list_widget.item(0).data(Qt.UserRole).data == 4
assert list_widget.item(1).data(Qt.UserRole).data == 5
assert list_widget.item(2).data(Qt.UserRole).data == 6
# Finally, if there are too few choices for the default_index to be valid,
# pick the last item in the list_widget
a_prop.set_choices(t, (9,))
assert t.a == 9
assert len(list_widget.selectedItems()) == 1
assert list_widget.selectedItems()[0] is list_widget.item(0)
assert list_widget.count() == 1
assert list_widget.item(0).text() == 'value: 9'
assert list_widget.item(0).data(Qt.UserRole).data == 9
# Now just make sure that ChoiceSeparator works
separator = ChoiceSeparator('header')
a_prop.set_choices(t, (separator, 1, 2))
assert list_widget.count() == 3
assert list_widget.item(0).text() == 'header'
assert list_widget.item(0).data(Qt.UserRole).data is separator
# And setting choices to an empty iterable shouldn't cause issues
a_prop.set_choices(t, ())
assert list_widget.count() == 0
# Try including an array in the choices
a_prop.set_choices(t, (4, 5, np.array([1, 2, 3])))
def test_connect_list_widget_selection_invalid():
t = Example()
list_widget = QtWidgets.QListWidget()
with pytest.raises(TypeError) as exc:
connect_list_selection(t, 'b', list_widget)
assert exc.value.args[0] == 'connect_list_selection requires a SelectionCallbackProperty'
|