Qtextedit Set Size

20 views
Skip to first unread message

Frida Kosofsky

unread,
Jul 25, 2024, 3:42:54 AM7/25/24
to throsseademe

I have a very simple app with QTextEdit with AcceptRichText=false and font family and size set to specific values. Now, if I type any text, then delete it either by performing select all and pasting some text (can be even copied from the same QTextEdit), or simply deleting selected text and typing something new, font family and size get reset to what I think are default values for QTextEdit.

EDIT: Found out this has to do with me using QTextEdit::setFontFamily() and QTextEdit::setFontPointSize(), which seem to set font only at the cursor position, instead of QTextEdit::setFont(). Using the latter fixes the problem.
Still, described QTextEdit behaviour is inconsistent - text edit set not to accept rich text shouldn't ever display rich text, e.g. two font families at a time.

qtextedit set size


DOWNLOAD →→→ https://fancli.com/2zNlbk



I am sending you the zip file along with a screenshot of what happens when the message gets long, but could you give me some advice on how to align the other message when another user is sending the messages? Thanks for your availability (I sent the email to coder...@learnpyqt.com)

To wrap between words and only wrap in words when there is no space, you need to use QTextOption with QTextOption.WrapAtWordBoundaryOrAnywhere. To use this we need to change the sizeHint method a bit as without a painter we need to create a QTextDocument to do the calculation.

In your email you said " the style of the other users is applied to my speech bubble". I thought you meant all bubbles had the same style. If you mean you want to swap the colours/positions for you vs. them, then just edit the variables to swap them around, e.g.

I have files of data from an electronic instrument that I need to plot, and then be able to insert the plots in high quality into reports in a word processor. I'm using QCustomPlot to produce a graph in a promoted widget, then inserting the graph into a QTextEdit, and finally rendering the graph into an SVG file using QSvgGenerator. The vector nature of the data is preserved the whole way, and the SVG file can be inserted into the word processor document with the required high quality.

All bar one of the elements of the graph seem to be working fine. However, I'm having trouble with some text in a QCPItemText. I'm aiming to locate this close to the top of the plot, with its centre aligned to be above the centre of the x-axis. In the widget, this seems to be the case, but in the QTextEdit the rest of the plot has shrunk slightly, while the QCPItemText has not, resulting in it being a little to the right of where I want it. (Both the widget and the QTextEdit are set graphically in the form mainwindow.ui to be 471 x 271). Even though the effect is relatively small, why do the QCPItemText and the rest of the graph appear to scale differently?

In both the above cases, the rectangle around the text is close in to the text. However, in the SVG file, the rectangle is extended to the right of the text, typically by about a quarter of the length of the text itself. The appearance is quite different from how it is in the widget and the QCPItemText: neither the text nor the rectangle around the text is centred above the centre of the x-axis.

but unfortunately there remains a problem. The textEdit now displays what I want (see _of_textEdit.png?dl=0), but in the SVG file that it goes on to create, while the text rectangle ends are in the same position relative to the horizontal axis (i.e. at about 1.5 and 8.5), the text now does not fill the rectangle, and is justified to the left (see =0).

These two points represent a straight line that goes below the horizontal axis at its left end. In the promoted widget and the textEdit, the data line below the horizontal axis is hidden, but in the SVG file it is visible.

I've experimented and searched around in the last few days and I'm convinced it's an issue with QSvgGenerator. There are many bug reports on the Qt bug tracker reporting the problems that you're encountering when trying to render the plot. For example, the line clipping and text box problem:
QTBUG-28636
QTBUG-1865
QTBUG-52538
Unfortunately, all those bugs have been around for a long time and still haven't been addressed by the Qt team. That's very unfortunate, as it makes very essential parts of SVG functionality unavailable to Qt developers. They mention these limitations by only claiming "support for SVG 1.2 Tiny", which I guess is pretty tiny if it doesn't even support clipping. Even then I'd expect the QPainter backend for SVG to take that limitation into account and implement a clipped output to the SVG. But that's not how it is.

Anyhow, here are my further observations:
I can reproduce your font issues with SVG. I see them as two separate issues: For one, the SVG painter reports font metrics incorrectly, which leads to the wrong size of the text box (that's QTBUG-52538). I don't have a solution for this, since it's an issue with QSvgGenerator. The second issue is that SVG viewers generally mess up text if it uses fonts that are not available on the system, or that the generator associated to different fonts than the viewer. This is an oversight of the SVG standard, that font object dimensions aren't embedded and that font files themselves can't (yet) be embedded. So for unknown fonts, the viewer makes a wild guess and uses any seemingly similar font, which typically messes up spacing etc.
I could observe this behavior when, as in your example, keeping default fonts or using generic font family descriptors such as "Sans". If I change every font (i.e. axis tick label, axis tick, text element,...) to a specific font that was available on the system, such as "DejaVu Sans", the spacing issues were gone and the text elements appeared correctly when viewing the SVG file in Inkscape.

I can reproduce your clipping issue with SVG. But unfortunately this is also out of my influence since it's a limitation of the SVG 1.2 Tiny standard which Qt only supports. Additionally, If I inspect or "take apart" the SVG file in inkscape that QSvgGenerator creates, it's pretty clear that many strange things are going on. For example there are many layers of differently colored filled rectangles below the plot, which QCustomPlot definitely doesn't draw in its code.

All in all, I believe the QtSvg module is unsuitable for any slightly sophisticated output. Quite a sad situation that I didn't expect myself, since SVG is becoming more and more important for various applications.

Megasolid Idiom is a rich text word processor implemented in Python and Qt. You can use it to open, edit and save HTML-formatted files, with a WYSIWYG (what you see is what you get) format view. Only basic formatting, headings, lists and images are supported.

Megasolid Idiom uses the Qt built-in QTextEdit component for our rich text editor, which means that Qt handles a lot of the complicated faff of text editing. Support for rich text (rather than plain text) is enabled by default, or by setting .setAcceptRichText(True) on the editor.

The two handlers canInsertFromMimeData and insertFromMimeData are Qt's methods for acceptingmime data (e.g. images, or other objects) dropped onto your editor. The both receive a signalparameter source which receives a QMimeData object.Similar mechanisms are used for other widget types.

The QTextEdit component (which we've subclassed as TextEdit) has some additional setup requirements.We switch on rich text mode for the editor component and enable auto-formatting (currently only bullet listsfrom *). The default font is set to Times New Roman 12pt.

We need our toolbar to update automatically when clicking/selecting text within the editor. By connectingour custom slot (update_format) to the .selectionChanged signal from the editor, wereceive a signal every time the current selection changes.

The .currentFontChanged signal is emitted by the combobox whenever the font is changed, passing the selected font as a parameter. By connecting this to the .setCurrentFont slot on our editor, we can use the dropdown to update the editors' font.

Font size is handled with a standard QCombobox which we pre-fill with a default list from the constant FONT_SIZES. The .currentIndexChanged[str] signal emits the current value of the combobox when it is updated. This is passed to the editor .setFontPointSize using a lambda to wrap the call so we can convert it to a float first.

Style handling uses checkable (toggleable) QAction widgets. We add a key sequence for each widget to provide standard keyboard shortcuts (e.g. QKeySequence.Bold). Each .toggled signal is connected to an editor slot to trigger updates.

There is no .setFontBold handler, instead we must use .setFontWeight to set the weight specifically. Qt provides a set of default weights in the Qt namespace. The Bold handler wraps the call to .setFontWeight, setting it to QFont.Bold if enabled, or QFont.Normal if not.

We finally add the handlers for alignment formatting. These are set up as a QActionGroup because they aremutually exclusive: action groups function like radio buttons. Each action's .triggered signal is connected to set a specific alignment on the current paragraph via the editor .setAlignment. We again use a lambda to, allowing us to pass the specific alignment type to the target method.

Note the different approaches needed to toggle the status icons. Italic and underline are both availableas bool values from the editor, while we need to compare the current weight for bold. For alignments,we can compare the current alignment to the Qt namespace values Qt.AlignLeft.

The font size change is a bit unpleasant: we get the point size from the editor, convert it to an integer(to round down) and then to a string, to apply as the current text for the box. This is necessary sinceusers are free to enter any size value, even one not currently in the list.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktopapplications to make data-analysis tools more user-friendly, Python wasthe obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt.

4a15465005
Reply all
Reply to author
Forward
0 new messages