Skip to content

Commit 3459107

Browse files
committed
Added new test launcher
1 parent 211bf8f commit 3459107

37 files changed

Lines changed: 201 additions & 44 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
### Version 0.7.0 ###
55

6+
- Added new test launcher
67
- QwtPlot: added "flatStyle" option, a PythonQwt-exclusive feature improving
78
default plot style (without margin, more compact and flat look) -- option is
89
enabled by default

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![download count](https://img.shields.io/conda/dn/conda-forge/PythonQwt.svg)](https://www.anaconda.com/download/)
88
[![Documentation Status](https://readthedocs.org/projects/pythonqwt/badge/?version=latest)](https://pythonqwt.readthedocs.io/en/latest/?badge=latest)
99

10-
<img src="https://raw.githubusercontent.com/PierreRaybaut/PythonQwt/master/doc/images/panorama.png">
10+
<img src="https://raw.githubusercontent.com/PierreRaybaut/PythonQwt/master/doc/images/test_launcher.png">
1111

1212
The `PythonQwt` project was initiated to solve -at least temporarily- the
1313
obsolescence issue of `PyQwt` (the Python-Qwt C++ bindings library) which is

doc/images/test_launcher.png

110 KB
Loading

qwt/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
It consists of a single Python package named `qwt` which is a pure Python
1818
implementation of Qwt C++ library with some limitations.
1919
20-
.. image:: images/panorama.png
20+
.. image:: images/test_launcher.png
2121
2222
External resources:
2323
* Python Package Index: `PyPI`_

qwt/tests/__init__.py

Lines changed: 171 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,29 @@
99
======================
1010
"""
1111

12+
from __future__ import print_function
13+
1214
import os
1315
import os.path as osp
1416
import sys
1517
import subprocess
18+
import platform
19+
from qwt.qt.QtGui import (QWidget, QMainWindow, QVBoxLayout, QFormLayout,
20+
QCheckBox, QGroupBox, QGridLayout, QToolButton,
21+
QStyle, QToolBar, QAction, QIcon, QMessageBox)
22+
from qwt.qt.QtCore import Qt, QSize
23+
from qwt import QwtPlot
24+
25+
26+
TEST_PATH = osp.abspath(osp.dirname(__file__))
1627

1728

1829
def run_test(fname, wait=False):
1930
"""Run test"""
2031
os.environ['PYTHONPATH'] = os.pathsep.join(sys.path)
2132
args = " ".join([sys.executable, '"'+fname+'"'])
22-
print(args)
33+
if os.environ.get("TEST_UNATTENDED") is not None:
34+
print(args)
2335
if wait:
2436
subprocess.call(args, shell=True)
2537
else:
@@ -44,39 +56,181 @@ def get_tests(package):
4456
return tests
4557

4658

47-
def run():
48-
"""Run PythonQwt tests or test launcher (requires `guidata`)"""
59+
def run_all_tests(wait):
60+
"""Run all PythonQwt tests"""
4961
import qwt
50-
if os.environ.get("TEST_UNATTENDED") is None:
51-
try:
52-
from guidata.guitest import run_testlauncher
53-
run_testlauncher(qwt)
54-
return
55-
except ImportError:
56-
pass
5762
for fname in get_tests(qwt):
58-
run_test(fname, wait=True)
63+
run_test(fname, wait=wait)
64+
65+
66+
class TestLauncher(QMainWindow):
67+
"""PythonQwt Test Launcher main window"""
68+
ROWS = 5
69+
def __init__(self, parent=None):
70+
super(TestLauncher, self).__init__(parent)
71+
from qwt import __version__
72+
self.setWindowIcon(self.get_std_icon("FileDialogListView"))
73+
self.setWindowTitle("PythonQwt %s - Test Launcher" % __version__)
74+
self.setCentralWidget(QWidget())
75+
self.grid_layout = QGridLayout()
76+
self.centralWidget().setLayout(self.grid_layout)
77+
self.test_nb = None
78+
self.fill_layout()
79+
self.statusBar().show()
80+
self.setStatusTip("Click on any button to run a test")
81+
82+
def get_std_icon(self, name):
83+
"""Return Qt standard icon"""
84+
return self.style().standardIcon(getattr(QStyle, "SP_" + name))
85+
86+
def fill_layout(self):
87+
"""Fill grid layout"""
88+
import qwt
89+
for fname in get_tests(qwt):
90+
self.add_test(fname)
91+
toolbar = QToolBar(self)
92+
all_act = QAction(self.get_std_icon("DialogYesButton"), "", self)
93+
all_act.setIconText("Run all tests")
94+
all_act.triggered.connect(lambda checked: run_all_tests(wait=False))
95+
folder_act = QAction(self.get_std_icon("DirOpenIcon"), "", self)
96+
folder_act.setIconText("Open tests folder")
97+
open_test_folder = lambda checked: os.startfile(TEST_PATH)
98+
folder_act.triggered.connect(open_test_folder)
99+
about_act = QAction(self.get_std_icon("FileDialogInfoView"), "", self)
100+
about_act.setIconText("About")
101+
about_act.triggered.connect(self.about)
102+
for action in (all_act, folder_act, None, about_act):
103+
if action is None:
104+
toolbar.addSeparator()
105+
else:
106+
toolbar.addAction(action)
107+
toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
108+
self.addToolBar(toolbar)
109+
110+
def add_test(self, fname):
111+
"""Add new test"""
112+
if self.test_nb is None:
113+
self.test_nb = 0
114+
self.test_nb += 1
115+
row = (self.test_nb-1) % self.ROWS
116+
column = (self.test_nb-1) // self.ROWS
117+
bname = osp.basename(fname)
118+
button = QToolButton(self)
119+
button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
120+
shot = osp.join(TEST_PATH, "data", bname.replace(".py", ".png"))
121+
if osp.isfile(shot):
122+
button.setIcon(QIcon(shot))
123+
else:
124+
button.setIcon(self.get_std_icon("DialogYesButton"))
125+
button.setText(bname)
126+
button.setToolTip(fname)
127+
button.setIconSize(QSize(130, 80))
128+
button.clicked.connect(lambda checked, fname=fname: run_test(fname))
129+
self.grid_layout.addWidget(button, row, column)
130+
131+
def about(self):
132+
"""About test launcher"""
133+
from qwt.qt.QtCore import __version__ as qt_version
134+
QMessageBox.about( self, "About "+self.windowTitle(),
135+
"""<b>%s</b><p>Developped by Pierre Raybaut
136+
<br>Copyright &copy; 2020 Pierre Raybaut
137+
<p>Python %s, Qt %s on %s""" % \
138+
(self.windowTitle(), platform.python_version(),
139+
qt_version, platform.system()) )
59140

60141

61-
def test_widget(widget_class, size=None, title=None):
142+
def run(wait=True):
143+
"""Run PythonQwt tests or test launcher (requires `guidata`)"""
144+
if os.environ.get("TEST_UNATTENDED") is None:
145+
from qwt.qt.QtGui import QApplication
146+
app = QApplication([])
147+
launcher = TestLauncher()
148+
launcher.show()
149+
app.exec_()
150+
else:
151+
run_all_tests(wait=wait)
152+
153+
154+
class TestOptions(QGroupBox):
155+
"""Test options groupbox"""
156+
def __init__(self, parent=None):
157+
super(TestOptions, self).__init__("Test options", parent)
158+
self.setLayout(QFormLayout())
159+
self.hide()
160+
161+
def add_checkbox(self, title, label, slot):
162+
"""Add new checkbox to option panel"""
163+
widget = QCheckBox(label, self)
164+
widget.stateChanged.connect(slot)
165+
self.layout().addRow(title, widget)
166+
self.show()
167+
return widget
168+
169+
170+
class TestCentralWidget(QWidget):
171+
"""Test central widget"""
172+
def __init__(self, parent=None):
173+
super(TestCentralWidget, self).__init__(parent)
174+
self.setLayout(QVBoxLayout())
175+
self.options = TestOptions(self)
176+
self.add_widget(self.options)
177+
178+
def add_widget(self, widget):
179+
"""Add new sub-widget"""
180+
self.layout().addWidget(widget)
181+
if isinstance(widget, QwtPlot):
182+
plots = [widget]
183+
else:
184+
plots = widget.findChildren(QwtPlot)
185+
for index, plot in enumerate(plots):
186+
plot_name = plot.objectName()
187+
if not plot_name:
188+
plot_name = "Plot #%d" % (index + 1)
189+
widget = self.options.add_checkbox(plot_name,
190+
"Enable new flat style option", plot.setFlatStyle)
191+
widget.setChecked(plot.flatStyle())
192+
193+
194+
class TestWindow(QMainWindow):
195+
"""Test main window"""
196+
def __init__(self):
197+
super(TestWindow, self).__init__()
198+
self.setCentralWidget(TestCentralWidget())
199+
200+
def add_widget(self, widget):
201+
"""Add new sub-widget to central widget"""
202+
self.centralWidget().add_widget(widget)
203+
204+
205+
def test_widget(widget_class, size=None, title=None, options=True):
62206
"""Test widget"""
63207
from qwt.qt.QtGui import QApplication
64208
app = QApplication([])
65-
widget = widget_class()
209+
window = widget = widget_class()
210+
if options:
211+
if isinstance(widget, QMainWindow):
212+
original_central_widget = window.centralWidget()
213+
original_central_widget.setParent(None)
214+
new_central_widget = TestCentralWidget()
215+
window.setCentralWidget(new_central_widget)
216+
new_central_widget.add_widget(original_central_widget)
217+
else:
218+
window = TestWindow()
219+
window.add_widget(widget)
66220
if title is None:
67221
from qwt import __version__
68222
title = 'Test "%s" - PythonQwt %s' % (widget_class.__name__,
69223
__version__)
70-
widget.setWindowTitle(title)
224+
window.setWindowTitle(title)
71225
if size is not None:
72226
width, height = size
73-
widget.resize(width, height)
74-
widget.show()
227+
window.resize(width, height)
228+
229+
window.show()
75230
if os.environ.get("TEST_UNATTENDED") is None:
76231
app.exec_()
77232
return app
78233

79234

80235
if __name__ == '__main__':
81236
run()
82-
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ def __init__(self, *args):
8585
self.grid = QwtPlotGrid()
8686
self.grid.enableXMin(True)
8787
self.grid.attach(self)
88+
self.grid.setPen(QPen(Qt.darkGray, 1, Qt.DotLine))
8889

8990
# axes
9091
self.enableAxis(QwtPlot.yRight)
@@ -110,7 +111,7 @@ def __init__(self, *args):
110111
self.curve2.attach(self)
111112

112113
# alias
113-
fn = self.fontInfo().family()
114+
fn = "Helvetica"
114115

115116
# marker
116117
self.dB3Marker = m = QwtPlotMarker()
@@ -119,9 +120,9 @@ def __init__(self, *args):
119120
m.setLabelAlignment(Qt.AlignRight | Qt.AlignBottom)
120121
m.setLinePen(QPen(Qt.green, 2, Qt.DashDotLine))
121122
text = QwtText('')
122-
text.setColor(Qt.green)
123+
text.setColor(Qt.white)
123124
text.setBackgroundBrush(Qt.red)
124-
text.setFont(QFont(fn, 12, QFont.Bold))
125+
text.setFont(QFont(fn, 10, QFont.Light))
125126
m.setLabel(text)
126127
m.attach(self)
127128

@@ -132,7 +133,7 @@ def __init__(self, *args):
132133
text = QwtText('')
133134
text.setColor(Qt.red)
134135
text.setBackgroundBrush(QBrush(self.canvasBackground()))
135-
text.setFont(QFont(fn, 12, QFont.Bold))
136+
text.setFont(QFont(fn, 10, QFont.Bold))
136137

137138
m.setLabel(text)
138139
m.setSymbol(QwtSymbol(QwtSymbol.Diamond,
@@ -149,10 +150,11 @@ def __init__(self, *args):
149150
'[1-(\u03c9/\u03c9<sub>0</sub>)<sup>2</sup>+2j\u03c9/Q]'
150151
'<sup>-1</sup>'
151152
)
152-
text.setFont(QFont(fn, 12, QFont.Bold))
153-
text.setColor(Qt.blue)
154-
text.setBackgroundBrush(QBrush(Qt.yellow))
155-
text.setBorderPen(QPen(Qt.red, 2))
153+
text.setFont(QFont(fn, 10, QFont.Bold))
154+
text.setColor(Qt.white)
155+
text.setBackgroundBrush(QBrush(Qt.lightGray))
156+
text.setBorderPen(QPen(Qt.lightGray, 5))
157+
text.setBorderRadius(2)
156158
m.setLabel(text)
157159
m.attach(self)
158160

@@ -280,4 +282,4 @@ def selected(self, _):
280282

281283
if __name__ == '__main__':
282284
from qwt.tests import test_widget
283-
app = test_widget(BodeDemo, (540, 400))
285+
app = test_widget(BodeDemo, (640, 480))
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,4 @@ def run_benchmark(self, max_n, **kwargs):
168168

169169
if __name__ == '__main__':
170170
from qwt.tests import test_widget
171-
app = test_widget(BMDemo1)
171+
app = test_widget(BMDemo1, options=False)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from qwt.qt.QtGui import QPen, QBrush
1414
from qwt.qt.QtCore import QSize, Qt
1515

16-
from qwt.tests import CurveBenchmark as cb
16+
from qwt.tests import curve_benchmark1 as cb
1717

1818
if cb.USE_PYQWT5:
1919
from PyQt4.Qwt5 import QwtSymbol
@@ -64,4 +64,4 @@ def run_benchmark(self, max_n, **kwargs):
6464

6565
if __name__ == '__main__':
6666
from qwt.tests import test_widget
67-
app = test_widget(BMDemo2)
67+
app = test_widget(BMDemo2, options=False)

0 commit comments

Comments
 (0)