Skip to content

QtWS: Super Early Bird Tickets Available!

  • 0 Votes
    3 Posts
    657 Views
    I

    This is a pretty old post, but I recently tried to tackle this and wanted to write down some of my findings about this obscure corner of Qt. It is probable that not all of this correct, this is just my current understanding.

    The purpose of QAbstractTextDocumentLayout::draw is to paint all of the relevant text blocks in the document (typically by means of delegating to QTextLayout::draw which does the actual heavy lifting) as well as any additional decorations and elements that surround the actual text objects (e.g. frame borders, list bullets, etc). It is also responsible for drawing the text cursor marker if needed.

    The layout class operates in document coordinates, so the position or size of the viewport of the actual widget (if it is even a widget, it could be drawing to a printer) is of no concern. The given QPainter is already pre-configured to accept the document's coordinate system.

    What defines what elements the view wants painted is the context.clip rectangle. At least those elements that intersect with it should be painted, so a straightforward thing to do would be to iterate over all blocks in the document, and check if their bounding rectangle intersects with the clip rectangle. Given that all blocks should already have their layout in place by the time draw is called, this is relatively fast. Of course this can be further optimized based on the layout class' knowledge of how blocks are laid out, for example a plain-text-like layout that arranges blocks linearly can use some sort of binary search.

    It is allowed to draw more than the clip, so drawing all blocks every time is a valid approach, although inefficient. It is also possible that the given clip rectangle is invalid, in which case everything needs to be drawn anyway. Though, I haven't seen QTextEdit not provide a valid clip.

    Other members of the PaintContext:

    palette - if you want to use the view's palette pens and brushes to paint something, they are available through here, although most colors will be determined by the character format.

    selections - for the text editing widgets, those are the "extra selections". For each painted block, you'll want to check if any of the extra selections' cursor is relevant to that block, turn it into block-relative start and end positions, and collect into a list that will be provided to QTextLayout::draw.

    cursorPosition - position in characters (relative to the document) where the text cursor marker should be drawn. Straightforward implementation would figure out the relevant block containing that position, and if relevant to the draw call, delegate to its' layout's QTextLayout::drawCursor method. You can also paint your own cursor directly with the painter if you'd like something custom. It is -1 if no cursor is required. One thing I noticed is that QTextEdit repeatedly calls draw on the text cursor's immediate area on a timer, alternating cursorPosition between -1 and the actual position, so that' how it makes a blinking cursor. There is also something with additional negative values, that seems related to pre-edit text, which is something I don't fully understand yet.

  • 0 Votes
    22 Posts
    14k Views
    A

    @Nico1564 said in How to draw on Image loaded in a QGraphicsView:

    Yeah i know that this work but i need to draw with fonctions. I successed to do that but I don't want to have the GraphicsView at the beginning of the program, and i want to add draws like an Ellipse (and the image) when i click on buttons.

    These lines could just as well happen inside a button click

    QGraphicsEllipseItem* testItem = new QGraphicsEllipseItem(20,30,120,70,0); m_pScene->addItem(testItem);

    In that case, you would create an ellipse every time you pressed that button.

    I don't quite understand the "I don't want to have the GraphicsView at the beginning of the program" - maybe you could elaborate on that.

  • 0 Votes
    1 Posts
    808 Views
    No one has replied
  • Draw on a QChart

    Unsolved General and Desktop
    1
    0 Votes
    1 Posts
    1k Views
    No one has replied
  • 0 Votes
    2 Posts
    3k Views
    johngodJ

    Hi Clockwork

    I didnt read your code with much attention, but for starters if all you want is draw a triangle, check this tutorials I did https://bitbucket.org/joaodeusmorgado/opengltutorials
    I'm using vbos, to draw triangles. I'm using all OpenGL native calls, but should be pretty easy to convert to Qt OpenGL functions. I also recommend you this book wich is great, it has a lot of details that usually are ommited in other books http://alfonse.bitbucket.org/oldtut/index.html

  • 0 Votes
    10 Posts
    3k Views
    SGaistS

    You could use a QRubberBand to setup the line and once you release it add the QGraphicsLineItem to your scene.

  • 0 Votes
    3 Posts
    1k Views
    Q

    Thank you!

    Just perfect! :D

  • 0 Votes
    6 Posts
    3k Views
    mrjjM

    @AlvaroS
    ok. seems a bit messy.
    Do you really need a QGraphicsScene then ?
    You could also draw it as a custom control. you need zooming etc ?

    In any case, did u see this example
    http://doc.qt.io/qt-5/qtwidgets-graphicsview-diagramscene-example.html

    it even has arrowhead class :)

  • Draw a head arrow

    Unsolved General and Desktop
    2
    0 Votes
    2 Posts
    12k Views
    mrjjM

    The sample
    http://doc.qt.io/qt-5/qtwidgets-graphicsview-diagramscene-example.html
    has arrow class.
    Maybe it can provide inspiration.

  • 0 Votes
    12 Posts
    10k Views
    kshegunovK

    @SysTech

    Thanks again!

    You're very welcome.

    Those 3D displays are kind of handy for visualizing the radio output but they are right now pretty CPU intensive.

    If I may insert yet another suggestion here. While I don't believe you'd gain much by using OpenGL painting for the "waterfall" data, I think switching to it for the 3D displays would work better. I nice side effect would be that you can also render OpenGL from different threads, provided the appropriate locking mechanisms are in place. You could, as the most simple test, try using QOpenGLWidget for those FFT displays.

    Kind regards.

  • 0 Votes
    1 Posts
    2k Views
    No one has replied
  • 0 Votes
    19 Posts
    13k Views
    kshegunovK

    @as2388

    Yes there is, do the drawing in another thread on a QImage and then trigger the update with that image.

    I'd add to @SGaist's great point - even convert the image to a QPixmap in the worker (after drawing it), and in the paint event just splat it onto the widget.

  • 0 Votes
    1 Posts
    900 Views
    No one has replied
  • 0 Votes
    5 Posts
    3k Views
    TheBadgerT

    @Ramin
    Actually I have never seen such a library.

    What I have done in the past (3 years ago) was to draw some elements connected to each other using Qt Quick (QML) and it worked pretty good.

    Another option is to look at the new modelling plugin that will be part of Qt Creator 3.6. And since Qt Creator is open source, you can look at how it is done and perhaps use that as a starting point.