使用按钮将富文本添加到 QTextEdit

Posted

技术标签:

【中文标题】使用按钮将富文本添加到 QTextEdit【英文标题】:Add Rich Text into QTextEdit Using Buttons 【发布时间】:2021-01-11 09:18:40 【问题描述】:

在 PyQt5 中,我有一些创建按钮的代码。我还有一个 QTextEdit 小部件,我可以在其中输入文本。我想要的是每次单击按钮时,它都允许我向 QTextEdit 添加粗体文本,如果我再次单击它,它将停止添加粗体文本。我该怎么做?

这是我的代码:

#Import Module
from PyQt5.QtGui import QFont
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
from PyQt5 import QtGui
import sys

class AddToDeckWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(AddToDeckWindow, self).__init__()

        #Set The UI
        self.initUI()

        #Set The GUI Position And Size
        self.setGeometry(200, 200, 900, 710)

        #Set The GUI Title
        self.setWindowTitle("Add")

        #Set The GUI Icon
        self.setWindowIcon(QtGui.QIcon('give_way.png'))

        #Set The Translator
        _translate = QtCore.QCoreApplication.translate
        
    def initUI(self):

        #Set Font For The Bold Label Button
        boldFont = QFont()
        boldFont.setFamily(u"Corbel")
        boldFont.setPointSize(19)
        boldFont.setBold(True)
        boldFont.setWeight(75)

        #Create The Bold Label Button
        self.boldButton = QtWidgets.QLabel(self)
        self.boldButton.setText("B")
        self.boldButton.setFont(boldFont)
        self.boldButton.adjustSize()

        #Create The Text Box
        textBox = QtWidgets.QTextEdit(self)
        textBox.setGeometry(100, 100, 500, 200)

        #Set The Font
        font = QFont()
        font.setPointSize(14)
        textBox.setFont(font)

#Create A Windows
def window():
    app = QtWidgets.QApplication(sys.argv)
    win = AddToDeckWindow()

    #Centers The Window On The Screen
    qtRectangle = win.frameGeometry()
    centerPoint = QtWidgets.QDesktopWidget().availableGeometry().center()
    qtRectangle.moveCenter(centerPoint)
    win.move(qtRectangle.topLeft())


    win.show()
    sys.exit(app.exec_())

window()

这是我尝试将文本设置为粗体:

def textBoldAddToDeck(self, eve):
        self.isBoldText = not self.isBoldText
        if self.isBoldText == True:
            self.editFrontTextAddMenu.inserthtml("<b>hi</b>")
        elif self.isBoldText == False:
            self.editFrontTextAddMenu.insertHtml("</b>")
        print(self.isBoldText)

这是完整代码(我知道变量很长,我会尽快更改它们。):

#Import Module
from PyQt5.QtGui import QFont
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
from PyQt5 import QtGui
import sys

class AddToDeckWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super(AddToDeckWindow, self).__init__()

        #Set The UI
        self.initUI()

        #Set The GUI Position And Size
        self.setGeometry(200, 200, 1200, 946)

        #Set The GUI Title
        self.setWindowTitle("Add")

        #Set The GUI Icon
        self.setWindowIcon(QtGui.QIcon('MainFlashcardAppIcon.png'))

        #Set The Translator
        _translate = QtCore.QCoreApplication.translate
        
    def initUI(self):
        widAddToDeckWindow = QtWidgets.QWidget(self)
        self.setCentralWidget(widAddToDeckWindow)

        ###DEFINE IS BOLD VARIABLE###
        self.isBoldText = False
        
        
        #Create A Label
        self.typeLabelAddMenu = QtWidgets.QLabel(self)
        self.typeLabelAddMenu.setText("Type")
        
        font_typeLabelAddMenu = QFont()
        font_typeLabelAddMenu.setPointSize(9)
        
        self.typeLabelAddMenu.setFont(font_typeLabelAddMenu)
        self.typeLabelAddMenu.adjustSize()

        self.typeButtonAddMenu = QtWidgets.QPushButton(self)
        self.typeButtonAddMenu.setText("Basic")
        #self.typeButtonAddMenu.setStyleSheet("background-color: red")

        self.deckLabelAddMenu = QtWidgets.QLabel(self)
        self.deckLabelAddMenu.setText("Deck")

        self.deckLabelAddMenu.setFont(font_typeLabelAddMenu)
        self.deckLabelAddMenu.adjustSize()
        
        self.deckButtonAddMenu = QtWidgets.QPushButton(self)
        self.deckButtonAddMenu.setText("Default")


        vboxAddToDeckWindow_Main = QtWidgets.QVBoxLayout(self)

        hboxAddToDeckWindow_top = QtWidgets.QHBoxLayout()
        hboxAddToDeckWindow_top.setSpacing(27)
        hboxAddToDeckWindow_top.addWidget(self.typeLabelAddMenu)
        hboxAddToDeckWindow_top.addWidget(self.typeButtonAddMenu, 1)
        hboxAddToDeckWindow_top.addWidget(self.deckLabelAddMenu)
        hboxAddToDeckWindow_top.addWidget(self.deckButtonAddMenu, 1)
        hboxAddToDeckWindow_top.setAlignment(Qt.AlignTop)

        font_typeButtonAddMenu_setFont = QFont()
        font_typeButtonAddMenu_setFont.setPointSize(10)

        self.fieldButtonAddMenu_font = QtWidgets.QToolButton(self)
        self.fieldButtonAddMenu_font.setText("Fields...")
        self.fieldButtonAddMenu_font.setFont(font_typeButtonAddMenu_setFont)

        self.cardsButtonAddMenu_font = QtWidgets.QToolButton(self)
        self.cardsButtonAddMenu_font.setText("Cards...")
        self.cardsButtonAddMenu_font.setFont(font_typeButtonAddMenu_setFont)

        #Set Font For The Bold Label Button
        fontAddToDeckBold_setFont = QFont()
        fontAddToDeckBold_setFont.setFamily(u"Corbel")
        fontAddToDeckBold_setFont.setPointSize(19)
        fontAddToDeckBold_setFont.setBold(True)
        fontAddToDeckBold_setFont.setWeight(75)

        #Create The Bold Label Button
        self.textBoldButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textBoldButtonAddMenu_font.setText("B")
        self.textBoldButtonAddMenu_font.setFont(fontAddToDeckBold_setFont)

        #self.textBoldButtonAddMenu_font.mousePressEvent = self.textBoldAddToDeck  ##### CALL THE TEXT BOLD FUNCTION


        #Set Font For The Itallic Label Button
        fontAddToDeckItallic_setFont = QFont()
        fontAddToDeckItallic_setFont.setFamily(u"Corbel")
        fontAddToDeckItallic_setFont.setPointSize(19)
        fontAddToDeckItallic_setFont.setItalic(True)
        fontAddToDeckItallic_setFont.setBold(True)
        fontAddToDeckItallic_setFont.setWeight(75)

        #Create The Itallic Label Button
        self.textItallicButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textItallicButtonAddMenu_font.setText("I")
        self.textItallicButtonAddMenu_font.setFont(fontAddToDeckItallic_setFont)


        #Set Font For The Underline Label Button
        fontAddToDeckUnderline_setFont = QFont()
        fontAddToDeckUnderline_setFont.setFamily(u"Corbel")
        fontAddToDeckUnderline_setFont.setPointSize(19)
        fontAddToDeckUnderline_setFont.setUnderline(True)

        #Create The Underline Label Button
        self.textUnderlineButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textUnderlineButtonAddMenu_font.setText("U")
        self.textUnderlineButtonAddMenu_font.setFont(fontAddToDeckUnderline_setFont)


        #Set Font For The Superscript Label Button
        fontAddToDeckSuper_setFont = QFont()
        fontAddToDeckSuper_setFont.setFamily(u"Corbel")
        fontAddToDeckSuper_setFont.setPointSize(19)

        #Create The Subscript Label Button
        self.textSubButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textSubButtonAddMenu_font.setText("S<sub>2</sub>")
        self.textSubButtonAddMenu_font.setFont(fontAddToDeckSuper_setFont)


        #Create The Superscript Label Button
        self.textSuperButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textSuperButtonAddMenu_font.setText("S<sup>2</sup>")
        self.textSuperButtonAddMenu_font.setFont(fontAddToDeckSuper_setFont)


        #Create The Remove Formatting Label Button
        self.textRemoveFormatButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textRemoveFormatButtonAddMenu_font.setText("F<sub>x</sub>")
        self.textRemoveFormatButtonAddMenu_font.setFont(fontAddToDeckSuper_setFont)


        #Create The Set Colour Label Button
        self.textSetColorButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textSetColorButtonAddMenu_font.setFont(fontAddToDeckSuper_setFont)

        
        self.textSetColorButtonAddMenu_font.setStyleSheet(u"border :1px solid black;\n"
                                                            "border-radius: 15px;\n"
                                                            "background-color: rgb(0, 0, 0);")

        self.textSetColorButtonAddMenu_font.setMinimumSize(QtCore.QSize(40, 40))
        self.textSetColorButtonAddMenu_font.setMaximumSize(QtCore.QSize(40, 40))


        #Create The Choose Colour Label Button
        self.textChooseColorButtonAddMenu_font = QtWidgets.QLabel(self)
        self.textChooseColorButtonAddMenu_font.setFont(fontAddToDeckSuper_setFont)

        
        self.textChooseColorButtonAddMenu_font.setStyleSheet(u"border :1px solid black;\n"
                                                            "border-radius: 15px;\n"
                                                            "background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 0, 0, 255), stop:0.166 rgba(255, 255, 0, 255), stop:0.333 rgba(0, 255, 0, 255), stop:0.5 rgba(0, 255, 255, 255), stop:0.666 rgba(0, 0, 255, 255), stop:0.833 rgba(255, 0, 255, 255), stop:1 rgba(255, 0, 0, 255));")

        self.textChooseColorButtonAddMenu_font.setMinimumSize(QtCore.QSize(40, 40))
        self.textChooseColorButtonAddMenu_font.setMaximumSize(QtCore.QSize(40, 40))

        hboxAddToDeckWindow_setFont = QtWidgets.QHBoxLayout()
        hboxAddToDeckWindow_setFont.setSpacing(16)
        hboxAddToDeckWindow_setFont.addWidget(self.fieldButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.cardsButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addStretch()
        hboxAddToDeckWindow_setFont.addWidget(self.textBoldButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textItallicButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textUnderlineButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textSubButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textSuperButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textRemoveFormatButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textSetColorButtonAddMenu_font)
        hboxAddToDeckWindow_setFont.addWidget(self.textChooseColorButtonAddMenu_font)

        hboxAddToDeckWindow_setFont.setAlignment(Qt.AlignTop)
        

        self.editFrontTextAddMenu = QtWidgets.QTextEdit(self)
        self.editFrontTextAddMenu.setMinimumSize(800, 50)

        #Set The Font
        editFrontTextAddMenu_font = QFont()
        editFrontTextAddMenu_font.setPointSize(15)
        self.editFrontTextAddMenu.setFont(editFrontTextAddMenu_font)

        self.editBackTextAddMenu = QtWidgets.QTextEdit(self)
        self.editBackTextAddMenu.setMinimumSize(800, 80)

        #Set The Font

        self.editBackTextAddMenu.setFont(editFrontTextAddMenu_font)

        hboxAddToDeckWindow_editFrontText = QtWidgets.QGridLayout()

        #Create A Label
        self.FrontCardAddWindowLabel = QtWidgets.QLabel(self)
        self.FrontCardAddWindowLabel.setText("Front")
        
        self.FrontCardAddWindowLabel.setFont(font_typeLabelAddMenu)
        self.FrontCardAddWindowLabel.adjustSize()

        #Create A Label
        self.BackCardAddWindowLabel = QtWidgets.QLabel(self)
        self.BackCardAddWindowLabel.setText("Back")
        
        self.BackCardAddWindowLabel.setFont(font_typeLabelAddMenu)
        self.BackCardAddWindowLabel.adjustSize()

        hboxAddToDeckWindow_editFrontText.addWidget(self.FrontCardAddWindowLabel, 1, 1)
        hboxAddToDeckWindow_editFrontText.addWidget(self.editFrontTextAddMenu, 2, 1)
        hboxAddToDeckWindow_editFrontText.addWidget(self.BackCardAddWindowLabel, 3, 1)
        hboxAddToDeckWindow_editFrontText.addWidget(self.editBackTextAddMenu, 4, 1)
        hboxAddToDeckWindow_editFrontText.setColumnStretch(1, 1)
        #hboxAddToDeckWindow_editFrontText.setRowStretch(2, 1)
        #hboxAddToDeckWindow_editFrontText.setRowStretch(14, 14)



        #Add The Horizontal Layouts To A Main Vertical Layout
        vboxAddToDeckWindow_Main.addLayout(hboxAddToDeckWindow_top)
        vboxAddToDeckWindow_Main.addLayout(hboxAddToDeckWindow_setFont)
        vboxAddToDeckWindow_Main.addLayout(hboxAddToDeckWindow_editFrontText)
        vboxAddToDeckWindow_Main.addStretch()
        

        widAddToDeckWindow.setLayout(vboxAddToDeckWindow_Main)

    def textBoldAddToDeck(self, eve):
        self.isBoldText = not self.isBoldText
        if self.isBoldText == True:
            self.editFrontTextAddMenu.insertHtml("<b>")
        elif self.isBoldText == False:
            self.editFrontTextAddMenu.insertHtml("</b>")
        print(self.isBoldText)

#Create A Windows
def window():
    app = QtWidgets.QApplication(sys.argv)
    win = AddToDeckWindow()

    #Centers The Window On The Screen
    qtRectangle = win.frameGeometry()
    centerPoint = QtWidgets.QDesktopWidget().availableGeometry().center()
    qtRectangle.moveCenter(centerPoint)
    win.move(qtRectangle.topLeft())


    win.show()
    sys.exit(app.exec_())

window()

但是,它没有用。谁能帮帮我

【问题讨论】:

这两个代码有什么关系?什么叫editFrontTextAddMenuself.isBoldText 在哪里声明?顺便说一句,我看到你仍然没有正确使用 QMainWindow 中的布局和小部件,我强烈建议你不要忽视这件事。 这部分只是完整代码的一小部分。我现在已经编辑了完整的代码,实际上我已经使用了布局(很好的建议!谢谢!) 为了将来参考,避免粘贴那么多代码。示例应始终尽可能少(但仍可重现)。我知道要减少从完整程序中提取的示例并不容易,但这就是 好帖子 的意义所在(以及为您提供更高投票率的原因)。带有大量示例的问题通常会被忽略,从而限制了答案的可能性。需要很多时间吗?是的,因为要给你一个好的答案需要很多时间。考虑到高质量的帖子通常需要 小时 (即使是为了回答!),但这并不是没有代价的,因为它总是以某种方式支付。 Then: 1) vboxAddToDeckWindow_Main 不应以self 作为父级创建(它会自动将布局设置为参数小部件):在这种情况下,self 是主窗口,并且禁止在 QMainWindow 上设置布局; 2) 除非绝对必要,否则不要将标签用作按钮;在您的情况下,为了使事情更容易并避免绘制图标,请使用 QToolButton,然后为其设置一个简单的 QHBoxLayout,调用buttonLayout.setContentsMargins(0, 0, 0, 0),然后将标签添加到具有正确对齐方式的布局中:buttonLayout.addWidget(buttonLabel, alignment=QtCore.Qt.AlignCenter) 好的。我现在就做这些改变。谢谢!将来,我会确保避免添加大量代码。再次感谢! 【参考方案1】:

要记住的重要一点是,Qt 的富文本功能受到部分限制,它们符合完整 HTML 标准。

使用 setHtml()insertHtml() 不会完全设置/附加参数中使用的确切 html。给定的 html 被解析为符合 Qt 的富文本段,然后合并到底层的 QTextDocument。

如果您尝试打印toHtml() 的输出,结果很清楚,这与您使用的不同。这是toHtml() 在附加粗体文本之前的输出(我跳过了标题):

<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; 
-qt-block-indent:0; text-indent:0px;">not bold</p>

这是在使用insertHtml("&lt;b&gt;bold&lt;/b&gt;")之后:

<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; 
-qt-block-indent:0; text-indent:0px;">not bold</p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; 
-qt-block-indent:0; text-indent:0px;">
<span style=" font-weight:600;">bold</span></p>

如您所见,没有&lt;b&gt; 标记的痕迹,而是转换为&lt;span&gt;

在您的情况下,会发生简单的&lt;b&gt; 被忽略,因为它没有有效内容:虽然 Qt 足够聪明,可以关闭已打开的标签,但没有文本,所以实际上什么都没有添加到文档中。

正确的解决方案其实更简单,因为QTextEdit已经提供了一些函数来改变当前光标位置的格式(如文档的Using QTextEdit as an Editor部分所述),包括setFontWeight()

        if self.isBoldText == True:
            self.editFrontTextAddMenu.setFontWeight(QtGui.QFont.Bold)
        elif self.isBoldText == False:
            self.editFrontTextAddMenu.setFontWeight(QtGui.QFont.Normal)

【讨论】:

啊我现在明白了!非常感谢@musicamante!

以上是关于使用按钮将富文本添加到 QTextEdit的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 java 邮件将富文本内容类型的邮件发送到 Outlook

将富文本数据从 Access 传输到 Word

将富文本和图像从一个文档复制到另一个文档的 MIME

java 解析富文本处理 img 标签

谁会将富文本编辑器代码插入到html页面中

将富编辑控件中的整个文本作为 CString 获取的各种方法