Remove space from QLabel in a QTreeWidget - qt

I've added QLabel widgets to my QTreeWidget to work around the word wrapping issue in QTreeWidget. (see how to word wrap a QTreeWidgetItem). The QLabel widgets appear to have spacing around the text which for some reason disappears when the text wraps. It also does not show up when the Label text is blank.
I tried setting setContentsMargin(0,0,0,0) on the QLabel but that didn't work. I also tried setStyleSheet("border: 0px; margin: 0px; padding: 0px;") which also didn't help.
Screenshot:
You can see that it depends on the length of the description whether QT decides to put that spacing buffer around the words. It only happens when the word wrap is enabled. Further playing around seems to indicate its dependent on spaces in the description string. No spaces in the string prevents the additional space around the words. Probably something to do with what the QLabel is doing with its word wrap property.
# This code is Ruby because I'm using the qtbindings gem
tree = Qt::TreeWidget.new
tree.setColumnCount(2)
tree.setHeaderLabels(["Name", "Description"])
top_node = Qt::TreeWidgetItem.new(["top"])
top_node.setCheckState(0, Qt::Unchecked)
tree.addTopLevelItem(top_node)
desc_label = Qt::Label.new("description")
desc_label.setWordWrap(true) # Remove and it works
tree.setItemWidget(top_node, 1, desc_label)
node = Qt::TreeWidgetItem.new(["test1"])
node.setCheckState(0, Qt::Unchecked)
top_node.addChild(node)
desc_label = Qt::Label.new("description1 is long and very interesting")
desc_label.setWordWrap(true) # Remove and it works
tree.setItemWidget(node, 1, desc_label)

What you see is effect of layouting logic for drawing/positioning of QLabel (you may see these routines in https://qt.gitorious.org/qt/qt/source/f7b3072924fb57b3979ff4d536eb213270be1047:src/gui/widgets/qlabel.cpp#sizeForWidth, see sizeForWidth() method).
What you may do is:
You may change the behavior little by trying to set setTextFormat() and use PlainText or RichText for all custom items explicitly. But it may not help.
My recommendation is to subclass used QItemDelegate or QStyledItemDelegate and reimplement the sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) for returning desired size, height for you customized item. Then to use setItemDelegate() to view.

My workaround was to set the label's minimum height as follows:
desc_label.setMinimumHeight(desc_label.fontMetrics.height * 2)
This matches what the Label is doing automatically with some of the strings and prevents the inconsistenly sized labels with blank or one-word strings.

I solved the problem by setting the fixed height or maximum height:
label.setMaximumHeight(label.fontMetrics().height() * n);
or
label.setFixedHeight(label.fontMetrics().height() * n);
where n is max considered/estimated lines of the label content.
Unfortunately, setting the minimum height, label.setMinimumHeight(...) does not work, otherwise it was more rational since it is not clear that the wrapped text may have how much lines. Also label.setContentMargin(0,0,0,0) does not work.

Related

How to reduce spacing/padding/margin of the text inside QDoubleSpinBox or QSpinBox to zero?

Using Qt 4.8. I would like to set the space between the text of a QSpinBoxes/QDoubleSpinBoxes and the right border of the widget to zero. The left one of the following images is what I got, the right one is what I want:
Note that I use setButtonSymbols(QAbstractSpinBox::NoButtons) to remove the up/down arrows.
The spinboxes are styled using QSS where I can set:
The padding of the QSpinBox/QDoubleSpinBox to 0px.
The padding, the margin and the border of the QLineEdit inside the spinbox to 0px.
I have also created a custom QProxyStyle for the QLineEdit but I'm not able to find any related pixel metric enum that I can use to reduce the space
I can also try to mess around with the internal QLineControl class which is not possible without fiddling inside Qt's code base. (I have not tried this yet!)

QTextEdit::adjustSize() not working?

Setting text for QTextEdit:
te->setPlainText(“Something”) ;
te->adjustSize();
should wrap around “Something” only, instead the QTextEdit is expanding to its maximum Width-Height, can’t fix it..
When I select “Something” on run time, only “Something” is highlighted, no added extra white spaces.
Expectations: when text is small enough to fit on one Line, the text edit shouldn’t expand in height, when the text needs to wrap, only the extra line width should be added not the maximum width.
if adjustSize(); is not called, the text will wrap on the width that was set in the .ui in the Creator, won't dynamically expand horizontally nor vertically..
Some Info:
Horizontal Policy: ExpandingVertical Policy : MinimumExpanding
minimumSize : 2×22maximum Size : 300×100lineWrapMode:
WidgetWidth
Yes, looks like there is no easy way to count lines in QTextEdit.
adjustSize() is made for QWidget and is not reimplemented for QTextEdit, it is based on sizeHint().
You can use your own method to count lines, f.e.
You can use QFontMetrics to calculate width of every word in your text
You can set height to 22 and increment it until maximumHeight hitted or vertical scrollbar dissapears.
You can get some info from sources of QTextEdit itself and subclass it, reimplementing something (adjustSize()?) there.

QTextEdit display width vs text width

I'm creating a 'scrolling-text' class in Qt, using a QTextEdit (read-only, no scrollbars, moveCursor) and a QTimer - simple and working.
My problem is when the text sent to the class is shorter (narrower) than the QTextEdit-box.
Silly, I agree, but, being new to Qt, I didn't find an easy way to compare the width of the given text (depending on the font) and the actual width that can be displayed inside the QTextEdit (after calculating the FrameStyle, etc.). I presume I need to calculate the pixels.
Any ideas?
Thanks
You can get the width of a text using QFontMetrics:
int textWidth = myTextEdit->fontMetrics().width(myTextEdit->text());

Hiding text with QSyntaxHighlighter

Problem: I want to implement a text editing widget for text with additional tags.
I'd like some tags to be invisible in some cases so that they do not distract the user.
Environment: I'm using PyQt and prefer to use QPlainTextWidget and QSyntaxHighlighter.
Approach: With QSyntaxHighlighter I can set QTextCharFormat for the strings which match my requirement. QTextCharFormat has gives me all font properties like size, colors, etc. but: I haven't found a option to hide the text or reduce its size to zero.
I don't want to remove or replace the tags, as this will introduce a lot more code (copying should contain tags and without I can't use QSyntaxHighlighter for formating the remaining text according to the tags).
Update: So far I found a ugly hack. By setting the QTextFormat::FontLetterSpacing to a small value, the text will consume less and less space. In combination with a transparent color the text is something like invisible.
Problem: In my test this worked only for letter spacings down to 0.016 %. Below the spacing is reseted to 100 %.
You can use the underlying QTextDocument for this. It consists of blocks whose visibility can be turned on and off using setVisible. Use a QTextCursor to insert the text and new blocks and switch visibility. As a bonus the copy function copies the content of non-visible blocks anyway.
Notes: See the documentation of QTextCursor for more information. In another question here is was reported that setting the visibility is not working on QTextEdits.
Example:
from PyQt5 import QtWidgets, QtGui
app = QtWidgets.QApplication([])
w = QtWidgets.QPlainTextEdit()
w.show()
t = QtGui.QTextCursor(w.document())
t.insertText('plain text')
t.insertBlock()
t.insertText('tags, tags, tags')
t.block().setVisible(False)
print(w.document().toPlainText())
app.exec_()

A real drawText call in Flex?

I am now developing a Flex application in which I need to control each pixel of my control of Flex. I want to calculate that how width and how height of some text used in my control and do some layout stuff.After some searching I find that the only way to draw text in Flex is to use something like TextField. So, I use TextField to display text and try to get the width and height of the text through:
textfiled.getLineMetrics(0).width/.height;
But the real textfield is much more bigger than this, so I do:
textfield.width = textfiled.getLineMetrics(0).width;
textfield.height = textfiled.getLineMetrics(0).height;
But, the textfield get part not displayed, and I am surprised by this effect. I know there should be a 2-pixel gutter around the text, but what the remain space? Why nearly 20% part of the text height/width are not displayed?
And how can I get a real drawText call in Flex, I mean something like Windows's drawText method...
Thanks!
you can try this : getCharBoundaries () i've used it and seems accurate hoever it is for char and not a whole text so you will need to iterate through the text
also see this :
Is there a way to get the actual bounding box of a glyph in ActionScript?
Please try:
textfield.width = textfield.textWidth + 4;
textfield.height = textfield.textHeight + 4;
I'm not familiar with Windows's drawText method so I cannot help you there, but perhaps you want to have a look at the stellar text layout functionality in Flex 4.

Resources