【问题标题】:How to vertically center a single-line in a QTextEdit instance (PySide/PyQt)?如何在 QTextEdit 实例(PySide/PyQt)中垂直居中单行?
【发布时间】:2016-01-01 16:23:00
【问题描述】:

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

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

也就是说,没有对垂直对齐的原生支持。有没有间接的方法让QTextEdit中的文本垂直居中?

相关链接

Center the Text of QTextEdit horizontally and vertically:不幸的是,接受的答案使用QLineEdit,这对我不起作用。

线索?

在下面我找到了关于如何在 C++/Qt 中执行此操作的线索。我几乎可以理解它,但并不完全,因为它是 c++ 的:

http://www.qtcentre.org/threads/26003-Vertical-centering-of-a-QTextEdit

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

【问题讨论】:

    标签: qt pyqt pyside


    【解决方案1】:

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

    使用example delegate from your previous question,可以这样实现:

    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)
    

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

    【讨论】:

    • 这很好用,而且比我试图从线索中获取的方法简单得多。
    • 所以当我改变字体大小时,这开始表现得很奇怪(文本在两个垂直位置之间切换,每次击键来回切换)。当我足够增加边距时,这种情况就不会发生了,但是停止它所需的边距取决于字体大小!我现在正在努力解决这个问题,构建一个 SSCCE,当我弄清楚这个谜团时,我会在这里发布一个单独的问题。
    • 我把它作为一个单独的答案:如果你想要任意字体大小,上述方法会变得复杂......
    【解决方案2】:

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

    它使用QTextDocument 设置编辑器,然后将其分配给QTextEdit 实例。无论如何,QTextDocuments 为QTextEdits 提供了后端容器,并具有处理字体大小和边距的内置功能,并为编辑器提供了额外的控制层。

    在实践中,我发现使用 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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 2013-10-19
      • 2015-10-19
      • 2016-09-19
      • 2018-11-20
      • 1970-01-01
      • 2019-03-09
      相关资源
      最近更新 更多