QGraphicsTextItem 设置文本居中的文本宽度

问题描述 投票:0回答:1

我有一个 QGraphicsTextxtItem,稍后我将不得不使用 toHtml 函数来检索文本及其样式(用于将其写入 .ASS 文件)。目前,我对 QGraphicsTextItem 使用 setTextWidth() 来允许文本位于中心。当为 QGraphicsTextItem 设置文本宽度时,文本会换行,并且不会出现在 toHtml 函数中。

我找到了一种方法,可以在创建新行以及该行中的文本时将其显示在 toHtml 上,但是,我不喜欢这样,因为我希望用户能够键入并且 QGraphicsTextItem 文本宽度展开与它,同时使文本居中。如果有办法,那么 setTextWidth 不会自动创建新行,并且无需使用函数来检查每个 QGraphicsTextItem 上的每一行并向其添加
即可工作。

我尝试使用 document().contentsChange() 函数并用它调整 setTextWidth() 的大小,但有时它决定工作,然后又不行。下面的代码显示了我尝试让 QGraphicsTextItem 在用户键入时更改文本宽度:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsScene, QGraphicsView, QGraphicsTextItem, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt


class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Create the central widget and layout for the window
        self.central_widget = QWidget()
        self.layout = QVBoxLayout(self.central_widget)

        # Create QGraphicsView and QGraphicsScene
        self.view = QGraphicsView()
        self.scene = QGraphicsScene(self)
        self.view.setScene(self.scene)
        self.view.setSceneRect(0, 0, 400, 300)

        self.editable_text = QGraphicsTextItem()
        self.editable_text.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.editable_text.setFlags(QGraphicsTextItem.ItemIsSelectable | QGraphicsTextItem.ItemIsMovable | QGraphicsTextItem.ItemIsFocusable)

        self.editable_text.setHtml(f'<div style="text-align: center;">This is an example TEXT</div>')

        self.editable_text.setTextWidth(self.view.scene().width())
        self.editable_text.adjustSize()

        self.editable_text.document().contentsChange.connect(self.centre_text)
        self.editable_text.setFont(QFont('Arial', 20))

        self.scene.addItem(self.editable_text)


        # Add the QGraphicsView to the layout
        self.layout.addWidget(self.view)

        # Set the central widget of the QMainWindow
        self.setCentralWidget(self.central_widget)

    def centre_text(self):
        self.editable_text.setTextWidth(self.editable_text.textWidth())
        print(self.editable_text.textWidth())
        self.editable_text.adjustSize()




app = QApplication(sys.argv)
main_window = MyMainWindow()
main_window.resize(800, 500)
main_window.show()
sys.exit(app.exec_())


qt pyqt qgraphicstextitem
1个回答
0
投票

我尝试按照musicamante的建议进行操作,但无法使用 document().contentsChange() 信号动态增加它,因此我必须检查有多少行,并查看该行上有哪些文本来添加前面有“<.br>”。我还没有真正测试过那么多,但它可以工作,但不如动态改变大小那么有效:



import sys, re
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsScene, QGraphicsView, QGraphicsTextItem, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtGui import QFont, QTextOption
from PyQt5.QtCore import Qt

class TextItem(QGraphicsTextItem):
    def __init__(self, parent=None):
        super().__init__(parent)
        # Set text alignment to center
        option = QTextOption()
        option.setAlignment(Qt.AlignCenter)
        self.document().setDefaultTextOption(option)

class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Create the central widget and layout for the window
        self.central_widget = QWidget()
        self.layout = QVBoxLayout(self.central_widget)

        # Create QGraphicsView and QGraphicsScene
        self.view = QGraphicsView()
        self.scene = QGraphicsScene(self)
        self.view.setScene(self.scene)
        self.view.setSceneRect(0, 0, 400, 300)

        self.editable_text = TextItem()
        self.editable_text.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.editable_text.setFlags(QGraphicsTextItem.ItemIsSelectable | QGraphicsTextItem.ItemIsMovable | QGraphicsTextItem.ItemIsFocusable)
        self.editable_text.setTextWidth(self.view.scene().width())
        self.editable_text.adjustSize()

        self.editable_text.setPlainText('Centered Text test')
        self.editable_text.setFont(QFont('Arial', 20))

        self.scene.addItem(self.editable_text)


        # Add the QGraphicsView to the layout
        self.layout.addWidget(self.view)

        # Add a button to save text as HTML
        self.save_button = QPushButton("Save as HTML")
        self.save_button.clicked.connect(self.save_as_html)
        self.layout.addWidget(self.save_button)

        # Set the central widget of the QMainWindow
        self.setCentralWidget(self.central_widget)

    def save_as_html(self):
        # Get the current HTML from the document
        existing_html = self.editable_text.document().toHtml()

        # Retrieve the wrapped lines with <br> tags
        wrapped_lines = self.get_wrapped_lines()
        html_with_br = "<br>".join(wrapped_lines)

        # Replace the content inside the <p> tags with the new content
        # Find all <p> tags
        paragraphs = re.findall(r'(<p[^>]*>)(.*?)(</p>)', existing_html, re.DOTALL)

        # Combine the new content into the existing HTML, replacing old content inside <p> tags
        new_html = existing_html
        for opening_tag, old_content, closing_tag in paragraphs:
            new_html = new_html.replace(f'{opening_tag}{old_content}{closing_tag}', f'{opening_tag}{html_with_br}{closing_tag}', 1)

        # Write the updated HTML content to the file
        with open("text_files.html", "w") as file:
            file.write(new_html)

        print("HTML file updated successfully.")



    def get_wrapped_lines(self):
        # Initialize a list to store lines
        lines = []

        # Get the text document
        text_document = self.editable_text.document()

        # Iterate through the blocks in the document
        block = text_document.begin()
        while block.isValid():
            # Get the block's layout
            block_layout = block.layout()
            
            # Iterate through lines in the block's layout
            for i in range(block_layout.lineCount()):
                line = block_layout.lineAt(i)
                # Use the block's text to find the text in this line
                line_start = line.textStart()
                line_end = line_start + line.textLength()
                lines.append(block.text()[line_start:line_end])
            
            # Move to the next block
            block = block.next()
        
        return lines

app = QApplication(sys.argv)
main_window = MyMainWindow()
main_window.resize(800, 500)
main_window.show()
sys.exit(app.exec_())
© www.soinside.com 2019 - 2024. All rights reserved.