#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
**search_QLineEdit.py**
**Platform:**
Windows, Linux, Mac Os X.
**Description:**
This module defines the :class:`Search_QLineEdit` class.
**Others:**
"""
#**********************************************************************************************************************
#*** Future imports.
#**********************************************************************************************************************
from __future__ import unicode_literals
#**********************************************************************************************************************
#*** External imports.
#**********************************************************************************************************************
import functools
import os
from PyQt4.QtCore import QString
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QCompleter
from PyQt4.QtGui import QIcon
from PyQt4.QtGui import QLineEdit
from PyQt4.QtGui import QPixmap
from PyQt4.QtGui import QStyle
from PyQt4.QtGui import QToolButton
#**********************************************************************************************************************
#*** Internal imports.
#**********************************************************************************************************************
import foundations.exceptions
import foundations.verbose
import umbra.ui.common
from umbra.ui.widgets.active_QLabel import Active_QLabel
#**********************************************************************************************************************
#*** Module attributes.
#**********************************************************************************************************************
__author__ = "Thomas Mansencal"
__copyright__ = "Copyright (C) 2008 - 2013 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "thomas.mansencal@gmail.com"
__status__ = "Production"
__all__ = ["LOGGER", "Search_QLineEdit"]
LOGGER = foundations.verbose.installLogger()
#**********************************************************************************************************************
#*** Module classes and definitions.
#**********************************************************************************************************************
[docs]class Search_QLineEdit(QLineEdit):
"""
This class is a `QLineEdit <http://doc.qt.nokia.com/qlinedit.html>`_ subclass providing
a search field with clearing capabilities.
"""
def __init__(self,
parent=None,
uiSearchImage=None,
uiSearchClickedImage=None,
uiClearImage=None,
uiClearClickedImage=None):
"""
.. Sphinx: Statements updated for auto-documentation purpose.
:param parent: Widget parent. ( QObject )
:param uiSearchImage: Search button image path. ( String )
:param uiSearchClickedImage: Search button clicked image path. ( String )
:param uiClearImage: Clear button image path. ( String )
:param uiClearClickedImage: Clear button clicked image path. ( String )
"""
LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))
QLineEdit.__init__(self, parent)
# --- Setting class attributes. ---
self.__uiSearchImage = None
self.uiSearchImage = uiSearchImage or umbra.ui.common.getResourcePath("images/Search_Glass.png")
self.__uiSearchClickedImage = None
self.uiSearchClickedImage = uiSearchClickedImage or umbra.ui.common.getResourcePath(
"images/Search_Glass_Clicked.png")
self.__uiClearImage = None
self.uiClearImage = uiClearImage or umbra.ui.common.getResourcePath("images/Search_Clear.png")
self.__uiClearClickedImage = None
self.uiClearClickedImage = uiClearClickedImage or umbra.ui.common.getResourcePath(
"images/Search_Clear_Clicked.png")
self.__searchActiveLabel = Active_QLabel(self,
QPixmap(self.__uiSearchImage),
QPixmap(self.__uiSearchImage),
QPixmap(self.__uiSearchClickedImage))
self.__searchActiveLabel.setObjectName("Search_Field_activeLabel")
self.__searchActiveLabel.showEvent = lambda event: reduce(lambda *args: None,
(self.__setStyleSheet(), Active_QLabel.showEvent(self.__searchActiveLabel, event)))
self.__searchActiveLabel.hideEvent = lambda event: reduce(lambda *args: None,
(self.__setStyleSheet(), Active_QLabel.hideEvent(self.__searchActiveLabel, event)))
self.__clearButton = QToolButton(self)
self.__clearButton.setObjectName("Clear_Field_button")
self.__completer = QCompleter()
self.setCompleter(self.__completer)
self.__completerVisibleItemsCount = 16
Search_QLineEdit.__initializeUi(self)
self.__setClearButtonVisibility(self.text())
# Signals / Slots.
self.__clearButton.clicked.connect(self.clear)
self.textChanged.connect(self.__setClearButtonVisibility)
#******************************************************************************************************************
#*** Attributes properties.
#******************************************************************************************************************
@property
def uiSearchImage(self):
"""
This method is the property for **self.__uiSearchImage** attribute.
:return: self.__uiSearchImage. ( String )
"""
return self.__uiSearchImage
@uiSearchImage.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError)
def uiSearchImage(self, value):
"""
This method is the setter method for **self.__uiSearchImage** attribute.
:param value: Attribute value. ( String )
"""
if value is not None:
assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
"uiSearchImage", value)
assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("uiSearchImage", value)
self.__uiSearchImage = value
@uiSearchImage.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def uiSearchImage(self):
"""
This method is the deleter method for **self.__uiSearchImage** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiSearchImage"))
@property
def uiSearchClickedImage(self):
"""
This method is the property for **self.__uiSearchClickedImage** attribute.
:return: self.__uiSearchClickedImage. ( String )
"""
return self.__uiSearchClickedImage
@uiSearchClickedImage.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError)
def uiSearchClickedImage(self, value):
"""
This method is the setter method for **self.__uiSearchClickedImage** attribute.
:param value: Attribute value. ( String )
"""
if value is not None:
assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
"uiSearchClickedImage", value)
assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
"uiSearchClickedImage", value)
self.__uiSearchClickedImage = value
@uiSearchClickedImage.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def uiSearchClickedImage(self):
"""
This method is the deleter method for **self.__uiSearchClickedImage** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiSearchClickedImage"))
@property
def uiClearImage(self):
"""
This method is the property for **self.__uiClearImage** attribute.
:return: self.__uiClearImage. ( String )
"""
return self.__uiClearImage
@uiClearImage.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError)
def uiClearImage(self, value):
"""
This method is the setter method for **self.__uiClearImage** attribute.
:param value: Attribute value. ( String )
"""
if value is not None:
assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
"uiClearImage", value)
assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
"uiClearImage", value)
self.__uiClearImage = value
@uiClearImage.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def uiClearImage(self):
"""
This method is the deleter method for **self.__uiClearImage** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiClearImage"))
@property
def uiClearClickedImage(self):
"""
This method is the property for **self.__uiClearClickedImage** attribute.
:return: self.__uiClearClickedImage. ( String )
"""
return self.__uiClearClickedImage
@uiClearClickedImage.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(AssertionError)
def uiClearClickedImage(self, value):
"""
This method is the setter method for **self.__uiClearClickedImage** attribute.
:param value: Attribute value. ( String )
"""
if value is not None:
assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
"uiClearClickedImage", value)
assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
"uiClearClickedImage", value)
self.__uiClearClickedImage = value
@uiClearClickedImage.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def uiClearClickedImage(self):
"""
This method is the deleter method for **self.__uiClearClickedImage** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiClearClickedImage"))
@property
def searchActiveLabel(self):
"""
This method is the property for **self.__searchActiveLabel** attribute.
:return: self.__searchActiveLabel. ( QPushButton )
"""
return self.__searchActiveLabel
@searchActiveLabel.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
def searchActiveLabel(self, value):
"""
This method is the setter method for **self.__searchActiveLabel** attribute.
:param value: Attribute value. ( QPushButton )
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchActiveLabel"))
@searchActiveLabel.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def searchActiveLabel(self):
"""
This method is the deleter method for **self.__searchActiveLabel** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchActiveLabel"))
@property
def clearButton(self):
"""
This method is the property for **self.__clearButton** attribute.
:return: self.__clearButton. ( QPushButton )
"""
return self.__clearButton
@clearButton.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
def clearButton(self, value):
"""
This method is the setter method for **self.__clearButton** attribute.
:param value: Attribute value. ( QPushButton )
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "clearButton"))
@clearButton.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
@property
def completer(self):
"""
This method is the property for **self.__completer** attribute.
:return: self.__completer. ( QCompleter )
"""
return self.__completer
@completer.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
def completer(self, value):
"""
This method is the setter method for **self.__completer** attribute.
:param value: Attribute value. ( QCompleter )
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "completer"))
@completer.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def completer(self):
"""
This method is the deleter method for **self.__completer** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "completer"))
@property
def completerVisibleItemsCount(self):
"""
This method is the property for **self.__completerVisibleItemsCount** attribute.
:return: self.__completerVisibleItemsCount. ( Integer )
"""
return self.__completerVisibleItemsCount
@completerVisibleItemsCount.setter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
def completerVisibleItemsCount(self, value):
"""
This method is the setter method for **self.__completerVisibleItemsCount** attribute.
:param value: Attribute value. ( Integer )
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "completerVisibleItemsCount"))
@completerVisibleItemsCount.deleter
#*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def completerVisibleItemsCount(self):
"""
This method is the deleter method for **self.__completerVisibleItemsCount** attribute.
"""
raise foundations.exceptions.ProgrammingError(
"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "completerVisibleItemsCount"))
#******************************************************************************************************************
#*** Class methods.
#******************************************************************************************************************
[docs] def resizeEvent(self, event):
"""
This method reimplements the :meth:`QLineEdit.QResizeEvent` method.
:param event: Resize event. ( QResizeEvent )
"""
frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
searchActiveLabelSize = self.__searchActiveLabel.sizeHint()
self.__searchActiveLabel.move(self.rect().left() + frameWidth,
(self.rect().bottom() - searchActiveLabelSize.height()) / 2 + frameWidth / 2)
clearButtonSize = self.__clearButton.sizeHint()
self.__clearButton.move(self.rect().right() - frameWidth - clearButtonSize.width(),
(self.rect().bottom() - clearButtonSize.height()) / 2 + frameWidth / 2)
def __initializeUi(self):
"""
This method initializes the Widget ui.
"""
self.__clearButton.setCursor(Qt.ArrowCursor)
if self.__uiClearImage and self.__uiClearClickedImage:
pixmap = QPixmap(self.__uiClearImage)
clickedPixmap = QPixmap(self.__uiClearClickedImage)
self.__clearButton.setIcon(QIcon(pixmap))
self.__clearButton.setMaximumSize(pixmap.size())
# Signals / Slots.
self.__clearButton.pressed.connect(functools.partial(self.__clearButton.setIcon, QIcon(clickedPixmap)))
self.__clearButton.released.connect(functools.partial(self.__clearButton.setIcon, QIcon(pixmap)))
else:
self.__clearButton.setText("Clear")
self.__setStyleSheet()
frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
self.setMinimumSize(max(self.minimumSizeHint().width(), self.__clearButton.sizeHint().height() + frameWidth * 2),
max(self.minimumSizeHint().height(), self.__clearButton.sizeHint().height() + frameWidth * 2))
self.__completer.setCaseSensitivity(Qt.CaseInsensitive)
self.__completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
self.__completer.setMaxVisibleItems(self.__completerVisibleItemsCount)
def __setStyleSheet(self):
"""
This method sets the Widget stylesheet.
"""
frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
self.setStyleSheet(QString("QLineEdit {{ padding-left: {0}px; padding-right: {1}px; }}".format(
self.__searchActiveLabel.sizeHint().width() if self.__searchActiveLabel.isVisible() else 0 + frameWidth,
self.__clearButton.sizeHint().width() + frameWidth)))
def __setClearButtonVisibility(self, text):
"""
This method sets the clear button visibility.
:param text: Current field text. ( QString )
"""
if text:
self.__clearButton.show()
else:
self.__clearButton.hide()
#**********************************************************************************************************************
#*** Sphinx: Statements updated for auto-documentation purpose.
#**********************************************************************************************************************