PDA

View Full Version : Vertical centering in QTextEdit is off by 4 pixels



neuronet
2nd January 2016, 19:04
I have a QTextEdit that I'm using as a single line editor for some tree views: it lets you set the font size and vertical margins for the vertically centered text. The code is pasted below (note it is PySide). I set up the font and margins using a QTextDocument, and then assign that document to the QTextEdit instance. It works great at all margin and font size combinations, but there is one thing driving me nuts: the text is not actually correctly centered on the widget unless I shift it up by four pixels using setViewportMargins. Why?

Could it be related to the fact that QTextDocuments have default margins of 4? I doubt it, because I am manually setting the margins of the document.

Any ideas?

(Before you ask, I'm not using QLineEdit because I'm displaying html in my tree views...)

SSCCE

import sys
from PySide import QtGui, QtCore

class TextLineEdit(QtGui.QTextEdit):
topMarginCorrection = -4 #not sure why needed
returnPressed = QtCore.Signal()
def __init__(self, fontSize = 10, verticalMargin = 2, parent = None):
QtGui.QTextEdit.__init__(self, parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setLineWrapMode(QtGui.QTextEdit.NoWrap)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBa rAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.Scroll BarAlwaysOff)
self.setFontPointSize(fontSize)
self.setViewportMargins(-verticalMargin, self.topMarginCorrection , 0, 0) #left, top, right, bottom
#Set up document with appropriate margins and font
document = QtGui.QTextDocument()
currentFont = self.currentFont()
currentFont.setPointSize(fontSize)
document.setDefaultFont(currentFont)
document.setDocumentMargin(verticalMargin)
self.setFixedHeight(document.size().height())
self.setDocument(document)

def keyPressEvent(self, event):
'''stops return from returning newline'''
if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.returnPressed.emit()
event.accept()
else:
QtGui.QTextEdit.keyPressEvent(self, event)


def main():
app = QtGui.QApplication(sys.argv)
myLine = TextLineEdit(fontSize = 15, verticalMargin = 8)
myLine.show()
sys.exit(app.exec_())


if __name__ == "__main__":
main()

ChrisW67
2nd January 2016, 21:07
The line of text quite probably is centred but that line also includes the inter-line spacing and/or ascender/descender heights (even if there are neither of these in the actual text). You might be able to adjust out the inter-line space with QTextBlockFormat.

neuronet
3rd January 2016, 17:51
The line of text quite probably is centred but that line also includes the inter-line spacing and/or ascender/descender heights (even if there are neither of these in the actual text). You might be able to adjust out the inter-line space with QTextBlockFormat.

It is unlikely to have to do with ascender/descender heights because these depend on font size, and the 4 pixel correction works for every font size I have tried (from like 8 to 50). Line spacing would also depend on font size right?

I've never used text blocks, that could give me more flexibility. I'm more just curious where these four pixels are coming from so I can better understand the code before releasing it: it is working very well right now so don't actually want to mess with it. :)

ChrisW67
4th January 2016, 03:42
Line spacing would also depend on font size right?
Maybe, maybe not. Have you done the experiment?

QFontMetrics::leading() for the font might give you a size to work with.
You should also look at the margin functions in QTextBlockFormat and setting a line height of type QTextBlockFormat::FixedHeight equal to the available space in the "line" edit.