Increasing spaces between words,ordering words in columns - c++

Is there possibility to easily increase spaces between words in QTextEdit?
My only idea is to set space key event to insert more whitespaces, but i would better like some setting parameters solution?
Is there way to set words in columns in text edit. What I mean:
first word wordabc abcd
second word worda egdsa
third word wordb dafdd
With this I have no idea for now.

The QTextEdit can render html, so you could use table elements to achieve what you want.
#include <QtGui/QApplication>
#include <QtGui/QTextEdit>
int main(int argc, char *argv[])
{
QString html = "<html><body><table>";
html += "<tr><td>first word</td><td>wordabc</td><td>abcd</td></tr>";
html += "<tr><td>second word</td><td>worda</td><td>egdsa</td></tr>";
html += "<tr><td>third word</td><td>wordb</td><td>dafdd</td></tr>";
html += "</table></body></html>";
QApplication app(argc, argv);
QTextEdit textEdit;
textEdit.setHtml(html);
textEdit.show();
return app.exec();
}
You could also apply styling to the table for example by adding the width attribute to the td tag to push columns apart from each other.

You can apply QTextCharFormat to your text and use QTextCharFormat::setFontWordSpacing ( qreal spacing )

Related

QTextEdit::extraSelections do not work well on Linux/X11 when QTextEdit with wrapped lines has explicitly set small font size

I have recently found a bug in Qt on Linux and reported it to https://bugreports.qt.io/browse/QTBUG-108149 Tested on Ubuntu 20.04 and 22.04 with Qt 5.15.2, 6.2.4 and 6.4, all with X11. I also tested it on Windows 10 and macOS 12.6 and Wayland and these seem to work fine.
Here is a minimal reproducible example. The program should highlight every occurrence of "abcd" in the text edit. However if I set the font size of the text edit to 12 points or smaller, the words in every second line are NOT highlighted. If I do not specify the font size or set font point size of 13 or greater, the highlighting works fine. The same problem seems to be with QPlainTextEdit.
I get this (every second row not highlighted):
This is what I would expect (all rows highlighted):
#include <QApplication>
#include <QTextEdit>
void highlight(QTextEdit *textEdit)
{
QList<QTextEdit::ExtraSelection> highlights;
QString word = "abcd";
QString text = textEdit->toPlainText();
int pos = text.indexOf(word);
while (pos != -1)
{
int endPos = pos + word.length();
auto highlight = QTextEdit::ExtraSelection();
highlight.cursor = QTextCursor(textEdit->document());
highlight.cursor.setPosition(pos);
highlight.cursor.setPosition(endPos, QTextCursor::KeepAnchor);
highlight.format.setForeground(QApplication::palette().color(QPalette::Link));
highlights.append(highlight);
pos = text.indexOf(word, endPos);
}
textEdit->setExtraSelections(highlights);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextEdit w;
// THE NEXT LINES!!!
// If point size 12 or smaller is used, then every second
// row in the text edit is not highlighted.
// If commented out, then everything works fine.
// If point size 13 or greater is used, then everything works fine.
QFont f;
f.setPointSize(12);
w.setFont(f);
w.setPlainText("abcd abcd abcd abcd abcd abcd abcd abcd "
"abcd abcd abcd abcd abcd abcd abcd abcd");
highlight(&w);
w.show();
return a.exec();
}
Any ideas for any workaround until this bug gets officially fixed?

Qt 5.7 \n behavior

In a Qt 5.7 Console Application:
#include <QCoreApplication>
#include <QtDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString s = "MDJ\nTest.\n";
qDebug() << "MDJ\nTest.\n";
qDebug() << s;
/* Prints:
MDJ
Test.
MDJ\nTest.\n
*/
return a.exec();
}
i.e. the \n works as expected in a direct debug print, but is treated as just two plain characters when debug printing a (supposedly identical content) variable.
I'm encountering similar problems in Qt 5.7 Widget Applications as well.
I've searched the documentation, stackoverflow, and Qt Centre and I've been unable to discover what I'm doing wrong.
Could somebody please point me to a solution for this?
The docs give you hints:
<< QString()
Normally, QDebug prints the string inside quotes and transforms non-printable characters to their Unicode values (\u1234).
To print non-printable characters without transformation, enable the noquote() functionality. Note that some QDebug backends might not be 8-bit clean.
vs.
<< const char*
Writes the '\0'-terminated string, s, to the stream and returns a reference to the stream. The string is never quoted nor transformed to the output, but note that some QDebug backends might not be 8-bit clean.
Solution: qDebug().noquote() << "some\nspecial\nchars\n\tincluded"

QTextEdit doesn't display special characters not available on keyboard

I have to display some special characters like ¼, ½ etc. in a QTextEdit which are not on the QWERTY keyboard.I am able to type these characters in the QTextEdit and also able to paste them. But when I try to programatically set these characters QTextEdit displays an extra character 'Â'.
I do not get this problem while typing and pasting. These characters are typed with some Alt+[code] codes.
I am using Qt 4.8 on Windows 8 64bit.
#include<QtGui>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextEdit t;
t.setPlainText("¼2½ \n"); // QTextEdit displays=> ¼2½
// t.setHtml("¼2½ \n"); // QTextEdit displays=> ¼2½
// t.insertHtml("¼2½ \n"); // QTextEdit displays=> ¼2½
// t.insertPlainText("¼2½ \n"); // QTextEdit displays=> ¼2½
// also tried setHtml() with HTML code which works in Firefox didn't help me
t.show();
return a.exec();
}
How can I put these characters in a QTextEdit programatically without this extra character?
Your source code needs to be written in UTF-8 encoding, and you should use QStringLiteral in Qt 5 or QString::fromUtf8 in Qt 4. You won't have that problem then.
E.g.:
t.setPlainText(QStringLiteral("¼, ½")); // Qt 5
t.setPlainText(QString::fromUtf8("¼, ½")); // Qt 4
Ensure that the editor you're using is set to encode the file as UTF-8, not Latin 1 etc.
Use QTextCodec to display characters in UTF-8 encoding.
#include <QTextCodec>
...
QTextCodec* codec=QTextCodec::codecForName("UTF-8");
// QTextCodec::setCodecForLocale(codec); //if you want everything to be in UTF-8
QTextCodec::setCodecForCStrings(codec);
QApplication a(argc, argv);
...
Or convert characters in place:
t.setPlainText(QObject::trUtf8("¼2½ \n"));

Why does select(QTextCursor::BlockUnderCursor) include an extra junk character?

Windows 7 SP1
MSVS 2010
Qt 4.8.4
I am using QTextCursor to grab each block's text. I use select(QTextCursor::BlockUnderCursor) to grab the text and then go to the next block with movePosition(QTextCursor::NextBlock). But when I again select(QTextCursor::BlockUnderCursor) I get an extra junk character in the QString and the anchor has moved to the end of the previous block.
Using this for text.txt:
A
B
This code's comments walks through the issue and asks the questions:
#include <QTGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow* window = new QMainWindow;
QTextEdit* editor = new QTextEdit(window);
QTextDocument* document = new QTextDocument(window);
editor->setDocument(document);
QFile file("test.txt");
if (file.open(QFile::ReadOnly | QFile::Text))
editor->setPlainText(file.readAll());
QTextBlock block = document->begin();
QTextCursor* cursor = new QTextCursor(document);
int pos = cursor->position(); // = 0
int anchor = cursor->anchor(); // = 0
cursor->select(QTextCursor::BlockUnderCursor);
pos = cursor->position(); // = 1
anchor = cursor->anchor(); // = 0
QString text = cursor->selectedText(); // = "A"
int size = text.size(); // = 1
cursor->movePosition(QTextCursor::NextBlock);
pos = cursor->position(); // = 2
anchor = cursor->anchor(); // = 2
cursor->select(QTextCursor::BlockUnderCursor);
pos = cursor->position(); // = 3
anchor = cursor->anchor(); // = 1 Why not 2?
text = cursor->selectedText(); // "B" in debugger
// but text.at(0) = junk & test.at(1) = "B"
size = text.size(); // = 2 Why? Why not 1?
return app.exec();
}
It is not junk. The first character includes the U+2029 paragraph separator (HTML: 
 PSEP). In other words, selecting the block includes the starting paragraph separator. The first block doesn't have a starting SEP. Therefore, need to exclude the first character if one wants to extract the text alone of subsequent blocks.
The navigation values has to do with the nature of a QTextBlock, and how navigating by block and what is determined by BlockUnderCursor. The documentation gives some insight into this:
http://doc.qt.digia.com/main-snapshot/qtextblock.html#details
Here is another part of the documentation seemed helpful to me:
http://doc.qt.digia.com/main-snapshot/qtextblockformat.html#details
I haven't experimented with what you found, but here are some of my thoughts on it:
In some ways I think of it like pressing Ctrl+Up or Ctrl+Down in Windows in a MS Word document. Some of it may have to do with the line endings you are using. "\r\n" v. "\n". I know that sometimes the "eof" character is weird to work with. Some documents and formats require a new line before the end of file character.
Hope that helps.

qtextedit - resize to fit

I have a QTextEdit which act as "displayer" (editable to false). The text it displays is wordwrapped. Now I do wish to set the height of this textbox so that the text fits exactly (while also respecting a maximum height).
Basically the widget (in the same vertical layout) below the layout should get as much space as possible.
How can this be achieved most easily?
I found a pretty stable, easy solution using QFontMetrics!
from PyQt4 import QtGui
text = ("The answer is QFontMetrics\n."
"\n"
"The layout system messes with the width that QTextEdit thinks it\n"
"needs to be. Instead, let's ignore the GUI entirely by using\n"
"QFontMetrics. This can tell us the size of our text\n"
"given a certain font, regardless of the GUI it which that text will be displayed.")
app = QtGui.QApplication([])
textEdit = QtGui.QPlainTextEdit()
textEdit.setPlainText(text)
textEdit.setLineWrapMode(True) # not necessary, but proves the example
font = textEdit.document().defaultFont() # or another font if you change it
fontMetrics = QtGui.QFontMetrics(font) # a QFontMetrics based on our font
textSize = fontMetrics.size(0, text)
textWidth = textSize.width() + 30 # constant may need to be tweaked
textHeight = textSize.height() + 30 # constant may need to be tweaked
textEdit.setMinimumSize(textWidth, textHeight) # good if you want to insert this into a layout
textEdit.resize(textWidth, textHeight) # good if you want this to be standalone
textEdit.show()
app.exec_()
(Forgive me, I know your question is about C++, and I'm using Python, but in Qt they're pretty much the same thing anyway).
Unless there is something particular to the capabilities of a QTextEdit that you need, a QLabel with word wrap turned on will do exactly what you want.
Current size of the underlying text can be available via
QTextEdit::document()->size();
and I believe that using this we could resize the widget accordingly.
#include <QTextEdit>
#include <QApplication>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextEdit te ("blah blah blah blah blah blah blah blah blah blah blah blah");
te.show();
cout << te.document()->size().height() << endl;
cout << te.document()->size().width() << endl;
cout << te.size().height() << endl;
cout << te.size().width() << endl;
// and you can resize then how do you like, e.g. :
te.resize(te.document()->size().width(),
te.document()->size().height() + 10);
return a.exec();
}
In my case, I put my QLabel inside a QScrollArea. And if you are keen, you combine both and make your own widget.
Speaking of Python, I actually found .setFixedWidth( your_width_integer ) and .setFixedSize( your_width, your_height ) quite useful. Not sure if C has similar widget attributes.