Remove ``applet`` from the window layout.

        This method removes ``applet`` and implicitly deletes
        obsolete (ie. half-full) splitters in the process. If
        ``applet`` is the only visible applet in the layout then it
        will be replaced with the first invisible applet. If no
        invisible applets are left then the method does nothing.

        The ``applet`` parameter can either be an instance of
        ``QtmacsApplet`` or a string denoting an applet ID. In the
        latter case the ``qteGetAppletHandle`` method is used to fetch
        the respective applet instance.

        If ``applet`` does not refer to an existing applet then
        nothing happens.

        |Args|

        * ``applet`` (**QtmacsApplet**, **str**): the applet to remove
          from the layout.

        |Returns|

        * **None**

        |Raises|

        * **QtmacsArgumentError** if at least one argument has an invalid type.

def qteRemoveAppletFromLayout(self, applet: (QtmacsApplet, str)):
        """
        Remove ``applet`` from the window layout.

        This method removes ``applet`` and implicitly deletes
        obsolete (ie. half-full) splitters in the process. If
        ``applet`` is the only visible applet in the layout then it
        will be replaced with the first invisible applet. If no
        invisible applets are left then the method does nothing.

        The ``applet`` parameter can either be an instance of
        ``QtmacsApplet`` or a string denoting an applet ID. In the
        latter case the ``qteGetAppletHandle`` method is used to fetch
        the respective applet instance.

        If ``applet`` does not refer to an existing applet then
        nothing happens.

        |Args|

        * ``applet`` (**QtmacsApplet**, **str**): the applet to remove
          from the layout.

        |Returns|

        * **None**

        |Raises|

        * **QtmacsArgumentError** if at least one argument has an invalid type.
        """
        # If ``applet`` was specified by its ID (ie. a string) then
        # fetch the associated ``QtmacsApplet`` instance. If
        # ``applet`` is already an instance of ``QtmacsApplet`` then
        # use it directly.
        if isinstance(applet, str):
            appletObj = self.qteGetAppletHandle(applet)
        else:
            appletObj = applet

        # Return immediately if the applet does not exist in any splitter.
        for window in self._qteWindowList:
            split = self._qteFindAppletInSplitter(
                appletObj, window.qteAppletSplitter)
            if split is not None:
                break
        if split is None:
            return

        # If the applet lives in the main splitter and is the only
        # widget there it must be replaced with another applet. This
        # case needs to be handled separately from the other options
        # because every other splitter will always contain exactly two
        # items (ie. two applets, two splitters, or one of each).
        if (split is window.qteAppletSplitter) and (split.count() == 1):
            # Remove the existing applet object from the splitter and
            # hide it.
            split.widget(0).hide(True)

            # Get the next available applet to focus on. Try to find a
            # visible applet in the current window, and if none exists
            # then pick the first invisible one. If there is neither
            # a visible nor an invisible applet left then do nothing.
            nextApp = self.qteNextApplet(windowObj=window)
            if nextApp is None:
                nextApp = self.qteNextApplet(skipInvisible=False,
                                             skipVisible=True)
                if nextApp is None:
                    return

            # Ok, we found an applet to show.
            split.qteAddWidget(nextApp)
            return

        # ------------------------------------------------------------
        # If we got until here we know that the splitter (root or not)
        # contains (at least) two elements. Note: if it contains more
        # than two elements then there is a bug somewhere.
        # ------------------------------------------------------------

        # Find the index of the object inside the splitter.
        appletIdx = split.indexOf(appletObj)

        # Detach the applet from the splitter and make it invisible.
        appletObj.hide(True)

        # Verify that really only one additional element is left in
        # the splitter. If not, then something is wrong.
        if split.count() != 1:
            msg = ('Splitter has <b>{}</b> elements left instead of'
                   ' exactly one.'.format(split.count()))
            self.qteLogger.warning(msg)

        # Get a reference to the other widget in the splitter (either
        # a QtmacsSplitter or a QtmacsApplet).
        otherWidget = split.widget(0)

        # Is the other widget another splitter?
        if otherWidget._qteAdmin.widgetSignature == '__QtmacsLayoutSplitter__':
            # Yes, ``otherWidget`` is a QtmacsSplitter object,
            # therefore shift all its widgets over to the current
            # splitter.
            for ii in range(otherWidget.count()):
                # Get the next widget from that splitter. Note that we
                # always pick the widget at the 0'th position because
                # the splitter will re-index the remaining widgets
                # after each removal.
                obj = otherWidget.widget(0)
                if appletIdx == 0:
                    split.qteAddWidget(obj)
                else:
                    split.qteInsertWidget(1 + ii, obj)

            # Delete the child splitter.
            otherWidget.setParent(None)
            otherWidget.close()
        else:
            # No, ``otherWidget`` is a QtmacsApplet, therefore move it
            # to the parent splitter and delete the current one,
            # unless 'split' is the root splitter in which case
            # nothing happens.
            if split is not window.qteAppletSplitter:
                otherWidget.qteReparent(split.parent())
                split.setParent(None)
                split.close()