Source code for enaml.qt.qt_field
#------------------------------------------------------------------------------
# Copyright (c) 2012, Enthought, Inc.
# All rights reserved.
#------------------------------------------------------------------------------
from enaml.validation.client_validators import null_validator, make_validator
from .qt.QtGui import QLineEdit
from .qt.QtCore import Signal
from .qt_control import QtControl
ECHO_MODES = {
'normal': QLineEdit.Normal,
'password' : QLineEdit.Password,
'silent' : QLineEdit.NoEcho
}
class QtFocusLineEdit(QLineEdit):
""" A QLineEdit subclass which converts a lost focus event into
a lost focus signal.
"""
lostFocus = Signal()
def focusOutEvent(self, event):
self.lostFocus.emit()
return super(QtFocusLineEdit, self).focusOutEvent(event)
[docs]class QtField(QtControl):
""" A Qt4 implementation of an Enaml Field.
"""
#: The client side validator function for the field.
_validator = null_validator
#: The validator message for the validator.
_validator_message = ''
#: The list of submit triggers for when to submit a text change.
_submit_triggers = []
#: The last text value submitted to or sent from the server.
_last_value = None
#: A flag indicating whether the current field is invalid.
_is_error_state = False
#--------------------------------------------------------------------------
# Setup Methods
#--------------------------------------------------------------------------
[docs] def create(self, tree):
""" Create and initialize the underlying widget.
"""
super(QtField, self).create(tree)
self.set_text(tree['text'])
self.set_validator(tree['validator'])
self.set_submit_triggers(tree['submit_triggers'])
self.set_placeholder(tree['placeholder'])
self.set_echo_mode(tree['echo_mode'])
self.set_max_length(tree['max_length'])
self.set_read_only(tree['read_only'])
widget = self.widget()
widget.lostFocus.connect(self.on_lost_focus)
widget.returnPressed.connect(self.on_return_pressed)
widget.textEdited.connect(self.on_text_edited)
#--------------------------------------------------------------------------
# Private API
#--------------------------------------------------------------------------
def _submit_text(self, text):
""" Submit the given text as an update to the server widget.
Parameters
----------
text : unicode
The unicode text to send to the server widget.
"""
content = {'text': text}
self.send_action('submit_text', content)
def _validate_and_submit(self):
""" Validate the current text in the control, and submit it to
the server widget if it's valid.
"""
text = self.widget().text()
if text != self._last_value:
if self._validator(text):
self._clear_error_style()
self._submit_text(text)
self._last_value = text
else:
self._set_error_style()
def _set_error_style(self):
# A temporary hack until styles are implemented
s = 'QLineEdit { border: 2px solid red; background: rgb(255, 220, 220); }'
self.widget().setStyleSheet(s)
self._is_error_state = True
def _clear_error_style(self):
# A temporary hack until styles are implemented
self.widget().setStyleSheet('')
self._is_error_state = False
#--------------------------------------------------------------------------
# Signal Handlers
#--------------------------------------------------------------------------
[docs] def on_lost_focus(self):
""" The signal handler for 'lostFocus' signal.
"""
if 'lost_focus' in self._submit_triggers:
self._validate_and_submit()
[docs] def on_return_pressed(self):
""" The signal handler for 'returnPressed' signal.
"""
if 'return_pressed' in self._submit_triggers:
self._validate_and_submit()
def on_text_edited(self):
# Temporary kludge until styles are fully implemented
widget = self.widget()
if self._validator(widget.text()):
if self._is_error_state:
self._clear_error_style()
widget.setToolTip('')
else:
if not self._is_error_state:
self._set_error_style()
widget.setToolTip(self._validator_message)
#--------------------------------------------------------------------------
# Message Handlers
#--------------------------------------------------------------------------
[docs] def on_action_set_text(self, content):
""" Handle the 'set_text' action from the Enaml widget.
"""
self.set_text(content['text'])
[docs] def on_action_set_validator(self, content):
""" Handle the 'set_validator' action from the Enaml widget.
"""
self.set_validator(content['validator'])
[docs] def on_action_set_submit_triggers(self, content):
""" Handle the 'set_submit_triggers' action from the Enaml
widget.
"""
self.set_submit_triggers(content['submit_triggers'])
[docs] def on_action_set_placeholder(self, content):
""" Hanlde the 'set_placeholder' action from the Enaml widget.
"""
self.set_placeholder(content['placeholder'])
[docs] def on_action_set_echo_mode(self, content):
""" Handle the 'set_echo_mode' action from the Enaml widget.
"""
self.set_echo_mode(content['echo_mode'])
[docs] def on_action_set_max_length(self, content):
""" Handle the 'set_max_length' action from the Enaml widget.
"""
self.set_max_length(content['max_length'])
[docs] def on_action_set_read_only(self, content):
""" Handle the 'set_read_only' action from the Enaml widget.
"""
self.set_read_only(content['read_only'])
[docs] def on_action_invalid_text(self, content):
""" Handle the 'invalid_text' action from the Enaml widget.
"""
if self.widget().text() == content['text']:
self._set_error_style()
#--------------------------------------------------------------------------
# Widget Update Methods
#--------------------------------------------------------------------------
[docs] def set_text(self, text):
""" Set the text in the underlying widget.
"""
self.widget().setText(text)
self._last_value = text
self._clear_error_style()
[docs] def set_validator(self, validator):
""" Set the validator for the underlying widget.
"""
if validator is None:
self._validator = null_validator
self._validator_message = ''
else:
self._validator = make_validator(validator)
self._validator_message = validator.get('message', '')
[docs] def set_submit_triggers(self, triggers):
""" Set the submit triggers for the underlying widget.
"""
self._submit_triggers = triggers
[docs] def set_placeholder(self, text):
""" Set the placeholder text of the underlying widget.
"""
self.widget().setPlaceholderText(text)
[docs] def set_echo_mode(self, mode):
""" Set the echo mode of the underlying widget.
"""
self.widget().setEchoMode(ECHO_MODES[mode])
[docs] def set_max_length(self, length):
""" Set the maximum text length in the underlying widget.
"""
if length <= 0 or length > 32767:
length = 32767
self.widget().setMaxLength(length)
[docs] def set_read_only(self, read_only):
""" Set whether or not the widget is read only.
"""
self.widget().setReadOnly(read_only)