2015-10-05 4 views
3

У меня есть редактор строк, который наследует от QTextEdit, и я использую его для редактирования элементов обзора, которые показывают богатый текст. Второй параметр для QTextEdit.setAlignment является `QtAligntment» и the docs говорят:Как вертикально центрировать одиночную строку в экземпляре QTextEdit (PySide/PyQt)?

Допустимые выравнивания являются 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

Я рубить его на мою собственную пару дней и попытаться ответить на него сам, но хотел опубликуйте это сейчас, если кто-то уже его взломал или сделал это другим способом.

ответ

2

Для однострочного редактирования, центрированного по вертикали, вам просто нужно вычислить правильную фиксированную высоту.

Используя в 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) 

(NB: переопределен sizeHint и minimumSizeHint методы, вероятно, излишним в исходном примере).

+0

Это работает отлично и намного проще, чем метод, который я собирался попытаться использовать в качестве ключа. – neuronet

+0

, поэтому, когда я изменяю размер шрифта, это начинает действовать очень странно (текст переключается между двумя вертикальными позициями, переключаясь назад и вперед с каждым нажатием клавиши). Когда я увеличиваю маржу достаточно, это останавливается, но маржа, необходимая для ее остановки, зависит от размера шрифта! Я сейчас работаю над этим, строя SSCCE, и опубликую здесь или отдельный вопрос, когда я выясню тайну. – neuronet

+0

Я выразился в отдельном ответе: если вы хотите получить произвольные размеры шрифта, этот подход будет усложняться .... – neuronet

1

Хотя принятый ответ работает на размер шрифта по умолчанию, он ломается при изменении размера шрифта или вертикальных полей (см. Комментарии). Класс редактирования текстовой строки ниже центрирует текст по вертикали, для всех размеров шрифтов и вертикальных полей, которые я тестировал.

Он устанавливает редактор, используя QTextDocument, который затем присваивается экземпляру QTextEdit. QTextDocument s обеспечивают внутренние контейнеры для QTextEdit и в любом случае имеют встроенные функции для обработки размеров и полей шрифтов и дают дополнительный уровень контроля над редактором.

На практике я нашел, используя 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() 
Смежные вопросы