Skip to content

Commit 69e8d2d

Browse files
committed
Updated formlayout to include the float validator
1 parent 5c963ae commit 69e8d2d

File tree

1 file changed

+55
-11
lines changed

1 file changed

+55
-11
lines changed

lib/matplotlib/backends/qt4_editor/formlayout.py

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
formlayout
44
==========
55
6-
Module creating PyQt4 form dialogs/layouts to edit various type of parameters
6+
Module creating Qt form dialogs/layouts to edit various type of parameters
77
88
99
formlayout License Agreement (MIT License)
@@ -34,10 +34,11 @@
3434
"""
3535

3636
# History:
37+
# 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid)
3738
# 1.0.7: added support for "Apply" button
3839
# 1.0.6: code cleaning
3940

40-
__version__ = '1.0.9'
41+
__version__ = '1.0.10'
4142
__license__ = __doc__
4243

4344
DEBUG = False
@@ -53,14 +54,14 @@
5354
QDialogButtonBox, QHBoxLayout, QVBoxLayout, QDialog, QColor, QPushButton,
5455
QCheckBox, QColorDialog, QPixmap, QTabWidget, QApplication, QStackedWidget,
5556
QDateEdit, QDateTimeEdit, QFont, QFontComboBox, QFontDatabase, QGridLayout,
56-
QFormLayout) =\
57+
QFormLayout, QDoubleValidator) =\
5758
(QtGui.QWidget, QtGui.QLineEdit, QtGui.QComboBox, QtGui.QLabel,
5859
QtGui.QSpinBox, QtGui.QIcon, QtGui.QStyle, QtGui.QDialogButtonBox,
5960
QtGui.QHBoxLayout, QtGui.QVBoxLayout, QtGui.QDialog, QtGui.QColor,
6061
QtGui.QPushButton, QtGui.QCheckBox, QtGui.QColorDialog, QtGui.QPixmap,
6162
QtGui.QTabWidget, QtGui.QApplication, QtGui.QStackedWidget, QtGui.QDateEdit,
6263
QtGui.QDateTimeEdit, QtGui.QFont, QtGui.QFontComboBox, QtGui.QFontDatabase,
63-
QtGui.QGridLayout, QtGui.QFormLayout)
64+
QtGui.QGridLayout, QtGui.QFormLayout, QtGui.QDoubleValidator)
6465

6566
(Qt, SIGNAL, SLOT, QObject, QSize,pyqtSignature, pyqtProperty) =\
6667
(QtCore.Qt, QtCore.SIGNAL, QtCore.SLOT, QtCore.QObject, QtCore.QSize,
@@ -177,7 +178,6 @@ def qfont_to_tuple(font):
177178
return (unicode(font.family()), int(font.pointSize()),
178179
font.italic(), font.bold())
179180

180-
181181
class FontLayout(QGridLayout):
182182
"""Font selection"""
183183
def __init__(self, value, parent=None):
@@ -220,9 +220,15 @@ def get_font(self):
220220
return qfont_to_tuple(font)
221221

222222

223+
def is_edit_valid(edit):
224+
text = edit.text()
225+
state = edit.validator().validate(text, 0)[0]
226+
227+
return state == QDoubleValidator.Acceptable
228+
223229
class FormWidget(QWidget):
224230
def __init__(self, data, comment="", parent=None):
225-
super(FormWidget, self).__init__(parent)
231+
QWidget.__init__(self, parent)
226232
from copy import deepcopy
227233
self.data = deepcopy(data)
228234
self.widgets = []
@@ -236,7 +242,13 @@ def __init__(self, data, comment="", parent=None):
236242
print "*"*80
237243
print "COMMENT:", comment
238244
print "*"*80
239-
self.setup()
245+
246+
def get_dialog(self):
247+
"""Return FormDialog instance"""
248+
dialog = self.parent()
249+
while not isinstance(dialog, QDialog):
250+
dialog = dialog.parent()
251+
return dialog
240252

241253
def setup(self):
242254
for label, value in self.data:
@@ -284,6 +296,11 @@ def setup(self):
284296
field.setCheckState(Qt.Unchecked)
285297
elif isinstance(value, float):
286298
field = QLineEdit(repr(value), self)
299+
field.setValidator(QDoubleValidator(field))
300+
dialog = self.get_dialog()
301+
dialog.register_float_field(field)
302+
self.connect(field, SIGNAL('textChanged(QString)'),
303+
lambda text: dialog.update_buttons())
287304
elif isinstance(value, int):
288305
field = QSpinBox(self)
289306
field.setRange(-1e9, 1e9)
@@ -334,7 +351,7 @@ def get(self):
334351

335352
class FormComboWidget(QWidget):
336353
def __init__(self, datalist, comment="", parent=None):
337-
super(FormComboWidget, self).__init__(parent)
354+
QWidget.__init__(self, parent)
338355
layout = QVBoxLayout()
339356
self.setLayout(layout)
340357
self.combobox = QComboBox()
@@ -351,14 +368,18 @@ def __init__(self, datalist, comment="", parent=None):
351368
widget = FormWidget(data, comment=comment, parent=self)
352369
self.stackwidget.addWidget(widget)
353370
self.widgetlist.append(widget)
371+
372+
def setup(self):
373+
for widget in self.widgetlist:
374+
widget.setup()
354375

355376
def get(self):
356377
return [ widget.get() for widget in self.widgetlist]
357378

358379

359380
class FormTabWidget(QWidget):
360381
def __init__(self, datalist, comment="", parent=None):
361-
super(FormTabWidget, self).__init__(parent)
382+
QWidget.__init__(self, parent)
362383
layout = QVBoxLayout()
363384
self.tabwidget = QTabWidget()
364385
layout.addWidget(self.tabwidget)
@@ -373,6 +394,10 @@ def __init__(self, datalist, comment="", parent=None):
373394
self.tabwidget.setTabToolTip(index, comment)
374395
self.widgetlist.append(widget)
375396

397+
def setup(self):
398+
for widget in self.widgetlist:
399+
widget.setup()
400+
376401
def get(self):
377402
return [ widget.get() for widget in self.widgetlist]
378403

@@ -381,7 +406,7 @@ class FormDialog(QDialog):
381406
"""Form Dialog"""
382407
def __init__(self, data, title="", comment="",
383408
icon=None, parent=None, apply=None):
384-
super(FormDialog, self).__init__(parent)
409+
QDialog.__init__(self, parent)
385410

386411
self.apply_callback = apply
387412

@@ -398,8 +423,14 @@ def __init__(self, data, title="", comment="",
398423
layout = QVBoxLayout()
399424
layout.addWidget(self.formwidget)
400425

426+
self.float_fields = []
427+
self.formwidget.setup()
428+
401429
# Button box
402-
bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
430+
self.bbox = bbox = QDialogButtonBox(QDialogButtonBox.Ok
431+
|QDialogButtonBox.Cancel)
432+
self.connect(self.formwidget, SIGNAL('update_buttons()'),
433+
self.update_buttons)
403434
if self.apply_callback is not None:
404435
apply_btn = bbox.addButton(QDialogButtonBox.Apply)
405436
self.connect(apply_btn, SIGNAL("clicked()"), self.apply)
@@ -414,6 +445,19 @@ def __init__(self, data, title="", comment="",
414445
icon = QWidget().style().standardIcon(QStyle.SP_MessageBoxQuestion)
415446
self.setWindowIcon(icon)
416447

448+
def register_float_field(self, field):
449+
self.float_fields.append(field)
450+
451+
def update_buttons(self):
452+
valid = True
453+
for field in self.float_fields:
454+
if not is_edit_valid(field):
455+
valid = False
456+
for btn_type in (QDialogButtonBox.Ok, QDialogButtonBox.Apply):
457+
btn = self.bbox.button(btn_type)
458+
if btn is not None:
459+
btn.setEnabled(valid)
460+
417461
def accept(self):
418462
self.data = self.formwidget.get()
419463
QDialog.accept(self)

0 commit comments

Comments
 (0)