如何在QTextEdit实例(PySide/PyQt)中垂直居中一条直线?

如何在QTextEdit实例(PySide/PyQt)中垂直居中一条直线?,qt,pyqt,pyside,Qt,Pyqt,Pyside,我有一个从QTextEdit继承的行编辑器,我正在使用它编辑显示富文本的视图项。QTextEdit.setAlignment的第二个参数是'QTAlignment',表示: 有效的对齐方式有Qt.AlignLeft、Qt.AlignRight、Qt.AlignJustify和 Qt.AlignCenter(水平居中) 也就是说,没有对垂直对齐的本机支持。在QTextEdit中,是否有间接的方法使文本垂直居中 相关链接 :不幸的是,接受的答案使用了QLineEdit,这对我不起作用 线索? 在下面

我有一个从
QTextEdit
继承的行编辑器,我正在使用它编辑显示富文本的视图项。
QTextEdit.setAlignment
的第二个参数是'QTAlignment',表示:

有效的对齐方式有Qt.AlignLeft、Qt.AlignRight、Qt.AlignJustify和 Qt.AlignCenter(水平居中)

也就是说,没有对垂直对齐的本机支持。在
QTextEdit
中,是否有间接的方法使文本垂直居中

相关链接

:不幸的是,接受的答案使用了
QLineEdit
,这对我不起作用

线索?

在下面的部分中,我找到了一条关于如何在C++/Qt中实现这一点的线索。我几乎能够理解它,但不像c++那样完全理解:


我将自己动手破解几天,并尝试自己回答,但我想现在就发布这篇文章,以防有人已经破解了它或以不同/更好的方式完成了它。

对于垂直居中的单行编辑,您只需要计算一个正确的固定高度

使用,可以实现如下操作:

class RichTextLineEdit(QtGui.QTextEdit):   
    def __init__(self, parent=None):
        ...    
        margin = 1
        self.document().setDocumentMargin(margin)
        fontMetrics = QtGui.QFontMetrics(self.font())
        height = fontMetrics.height() + (margin + self.frameWidth()) * 2
        self.setFixedHeight(height)

(注意:重新实现的
sizeHint
minimumSizeHint
方法在原始示例中可能是多余的)。

虽然接受的答案适用于默认字体大小,但当我更改字体大小或垂直边距时,它会中断(请参见注释)。下面的文本行编辑类将文本垂直居中,适用于我测试过的所有字体大小和垂直边距

它使用
QTextDocument
设置编辑器,然后将该编辑器分配给
qtextdedit
实例
QTextDocument
s为
QTextEdit
s提供了后端容器,具有处理字体大小和边距的内置功能,并提供了对编辑器的额外控制层

在实践中,我发现使用
QTextDocument
让我以一种更直观的方式解决问题,而不必深入研究帧宽度、字体度量等的本质机制,这是我们单独使用本机
QTextEdit
方法时所做的

注意:它使用
setViewportMargins()
而不是
setContentMargins()
(这是您可能希望它使用的),因为后者用于为插入到布局中的内容设置边距。下面的编辑器是一个独立的小部件,没有放入任何布局,因此
setContentMargins()
不会做任何事情

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.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        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 retun 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()

这非常有效,比我试图从线索中推动的方法简单得多。因此,当我改变字体大小时,这开始表现得非常奇怪(文本在两个垂直位置之间切换,随着每个键的笔划来回切换)。当我增加足够的边距时,这种情况就停止了,但停止这种情况所需的边距取决于字体大小!我现在正致力于解决这个问题,构建一个SSCCE,当我解决了这个问题后,我会在这里发布一个单独的问题。我把它作为一个单独的答案:如果你想要任意的字体大小,上面的方法会变得复杂。。。。