[PyQt] Snippet to embed a widget in an editor.

Phlip phlip2005 at gmail.com
Sun Jul 17 04:57:00 BST 2011


Hi, group. I'm trying to embed an object into a QTextEdit which is NOT
(shocked gasp!) an SVG image.

Foundational for embedding a panel, I'm trying to embed a widget. But
I can't seem to get the size right. Here's the sauce:

#!/usr/bin/env python

try:
    # This is only needed for Python v2 but is harmless for Python v3.
    import sip
    sip.setapi('QVariant', 2)
except ImportError:
    pass

from PyQt4 import QtCore, QtGui


class YoWindow(QtGui.QWidget):

    TEXT_OBJECT_WRAPPER = QtGui.QTextFormat.UserObject + 1001

    def __init__(self):
        super(YoWindow, self).__init__()

        self.setWindowTitle('YoWindow')

        self.textEdit = QtGui.QTextEdit()
        widget = QtGui.QLineEdit()
        widget.setText('I am here!')
        self.text_object_wrapper(self.textEdit, widget)

        layout = _vertical( self.textEdit )

        self.setLayout(layout)

        cursor = self.textEdit.textCursor()
        cursor.insertText('previously\n')

        self.insertTextObject(cursor)

        cursor.insertText('subsequently')
        self.textEdit.setTextCursor(cursor)

    def text_object_wrapper(self, editor, widget):

        class _TextObject(QtGui.QPyTextObject):

            def intrinsicSize(self, doc, posInDocument, format):

                size = widget.baseSize()  #  <-- other sizes just gave
whack results
                return QtCore.QSizeF(size)

            def drawObject(self, painter, rect, doc, posInDocument, format):
                widget.render(painter, QtCore.QPoint(int(rect.x()),
int(rect.y())))

        interface = _TextObject(self)
        editor.document().documentLayout().registerHandler(YoWindow.TEXT_OBJECT_WRAPPER,
interface)

    def insertTextObject(self, cursor):

        charFormat = QtGui.QTextCharFormat()
        charFormat.setObjectType(YoWindow.TEXT_OBJECT_WRAPPER)

        try:
            # Python v2.
            orc = unichr(0xfffc)
        except NameError:
            # Python v3.
            orc = chr(0xfffc)

        cursor.insertText(orc, charFormat)


def _vertical(*things):
    return _lay_out(QtGui.QVBoxLayout, *things)

def _lay_out(LayoutClass, *things):
    layout = LayoutClass()

    for thing in things:
        if hasattr(thing, 'BottomToTop'):
            layout.addLayout(thing)
        else:
            layout.addWidget(thing)

    return layout


if __name__ == '__main__':

    import sys

    app = QtGui.QApplication(sys.argv)
    window = YoWindow()
    window.show()
    sys.exit(app.exec_())

If you ran that, you'd get:

   previously
   subsequently
   [I am here!]

Presumably if the size were set right, the editor would push down the
"subsequently".

Contrarily, maybe I'm setting the size correctly, but then screwing
something up with the cursors.

-- 
  Phlip
  http://c2.com/cgi/wiki?ZeekLand


More information about the PyQt mailing list