Defines a class factory creating `QWidget <http://doc.qt.nokia.com/qwidget.html>`_ classes
    using given ui file.

    :param ui_file: Ui file.
    :type ui_file: unicode
    :param \*args: Arguments.
    :type \*args: \*
    :param \*\*kwargs: Keywords arguments.
    :type \*\*kwargs: \*\*
    :return: QWidget class.
    :rtype: QWidget

def QWidget_factory(ui_file=None, *args, **kwargs):
    """
    Defines a class factory creating `QWidget <http://doc.qt.nokia.com/qwidget.html>`_ classes
    using given ui file.

    :param ui_file: Ui file.
    :type ui_file: unicode
    :param \*args: Arguments.
    :type \*args: \*
    :param \*\*kwargs: Keywords arguments.
    :type \*\*kwargs: \*\*
    :return: QWidget class.
    :rtype: QWidget
    """

    file = ui_file or DEFAULT_UI_FILE
    if not foundations.common.path_exists(file):
        raise foundations.exceptions.FileExistsError("{0} | '{1}' ui file doesn't exists!".format(__name__, file))

    Form, Base = uic.loadUiType(file)

    class QWidget(Form, Base):

        """
        Derives from :def:`QWidget_factory` class factory definition.
        """

        def __init__(self, *args, **kwargs):
            """
            Initializes the class.

            :param \*args: Arguments.
            :type \*args: \*
            :param \*\*kwargs: Keywords arguments.
            :type \*\*kwargs: \*\*
            """

            LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))

            super(QWidget, self).__init__(*args, **kwargs)

            self.__ui_file = file

            self.__geometry = None

            self.setupUi(self)

        @property
        def ui_file(self):
            """
            Property for **self.__ui_file** attribute.

            :return: self.__ui_file.
            :rtype: unicode
            """

            return self.__ui_file

        @ui_file.setter
        @foundations.exceptions.handle_exceptions(foundations.exceptions.ProgrammingError)
        def ui_file(self, value):
            """
            Setter for **self.__ui_file** attribute.

            :param value: Attribute value.
            :type value: unicode
            """

            raise foundations.exceptions.ProgrammingError("{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "ui_file"))

        @ui_file.deleter
        @foundations.exceptions.handle_exceptions(foundations.exceptions.ProgrammingError)
        def ui_file(self):
            """
            Deleter for **self.__ui_file** attribute.
            """

            raise foundations.exceptions.ProgrammingError("{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "ui_file"))

        def show(self, setGeometry=True):
            """
            Reimplements the :meth:`QWidget.show` method.

            :param setGeometry: Set geometry.
            :type setGeometry: bool
            """

            if not setGeometry:
                super(QWidget, self).show()
                return

            wasHidden = not self.isVisible()

            if self.__geometry is None and wasHidden:
                center_widget_on_screen(self)

            super(QWidget, self).show()

            if self.__geometry is not None and wasHidden:
                self.restoreGeometry(self.__geometry)

        def closeEvent(self, event):
            """
            Reimplements the :meth:`QWidget.closeEvent` method.

            :param event: QEvent.
            :type event: QEvent
            """

            self.__geometry = self.saveGeometry()
            event.accept()

    return QWidget