Completed
Branch master (6f2cba)
by Gonzalo
01:09
created

get_qapp()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 0 Features 0
Metric Value
cc 2
c 8
b 0
f 0
dl 0
loc 5
rs 9.4285
1
from __future__ import absolute_import
2
3
from qtpy import QtGui, QtWidgets
4
5
6
def get_qapp(icon_path=None):
7
    qapp = QtWidgets.QApplication.instance()
8
    if qapp is None:
9
        qapp = QtWidgets.QApplication([''])
10
    return qapp
11
12
13
class Data(object):
14
    """
15
    Test class to store in userData. The __getitem__ is needed in order to
16
    reproduce the segmentation fault.
17
    """
18
    def __getitem__(self, item):
19
        raise ValueError("Failing")
20
21
22
def test_patched_qcombobox():
23
    """
24
    In PySide, using Python objects as userData in QComboBox causes
25
    Segmentation faults under certain conditions. Even in cases where it
26
    doesn't, findData does not work correctly. Likewise, findData also
27
    does not work correctly with Python objects when using PyQt4. On the
28
    other hand, PyQt5 deals with this case correctly. We therefore patch
29
    QComboBox when using PyQt4 and PySide to avoid issues.
30
    """
31
32
    app = get_qapp()
33
34
    data1 = Data()
35
    data2 = Data()
36
    data3 = Data()
37
    data4 = Data()
38
    data5 = Data()
39
    data6 = Data()
40
41
    icon1 = QtGui.QIcon()
42
    icon2 = QtGui.QIcon()
43
44
    widget = QtWidgets.QComboBox()
45
    widget.addItem('a', data1)
46
    widget.insertItem(0, 'b', data2)
47
    widget.addItem('c', data1)
48
    widget.setItemData(2, data3)
49
    widget.addItem(icon1, 'd', data4)
50
    widget.insertItem(3, icon2, 'e', data5)
51
    widget.addItem(icon1, 'f')
52
    widget.insertItem(5, icon2, 'g')
53
54
    widget.show()
55
56
    assert widget.findData(data1) == 1
57
    assert widget.findData(data2) == 0
58
    assert widget.findData(data3) == 2
59
    assert widget.findData(data4) == 4
60
    assert widget.findData(data5) == 3
61
    assert widget.findData(data6) == -1
62
63
    assert widget.itemData(0) == data2
64
    assert widget.itemData(1) == data1
65
    assert widget.itemData(2) == data3
66
    assert widget.itemData(3) == data5
67
    assert widget.itemData(4) == data4
68
    assert widget.itemData(5) is None
69
    assert widget.itemData(6) is None
70
71
    assert widget.itemText(0) == 'b'
72
    assert widget.itemText(1) == 'a'
73
    assert widget.itemText(2) == 'c'
74
    assert widget.itemText(3) == 'e'
75
    assert widget.itemText(4) == 'd'
76
    assert widget.itemText(5) == 'g'
77
    assert widget.itemText(6) == 'f'
78
79
80
def test_model_item():
81
    """
82
    This is a regression test for an issue that caused the call to item(0)
83
    below to trigger segmentation faults in PySide. The issue is
84
    non-deterministic when running the call once, so we include a loop to make
85
    sure that we trigger the fault.
86
    """
87
    app = get_qapp()
88
    combo = QtWidgets.QComboBox()
89
    label_data = [('a', None)]
90
    for iter in range(10000):
91
        combo.clear()
92
        for i, (label, data) in enumerate(label_data):
93
            combo.addItem(label, userData=data)
94
        model = combo.model()
95
        model.item(0)
96