QTextBrowser 点击文字改变字体
QTextBrowser click on text changes font
我有一个奇怪的问题,我正在为聊天机器人创建 GUI,并且我选择了 PyQt5 Designer 来这样做。一切都运行良好,但现在我已经实现了一些 hyperlinks 并意识到当我在 QTextBrowser 中单击具有不同字体的行时,所有聊天机器人响应都会更改为该字体。
因此,例如,如果我单击 link,之后的每个答案都将被 hyperlinked.
代码片段:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_mainWindow(object):
def setupUi(self, mainWindow):
mainWindow.setObjectName("mainWindow")
mainWindow.resize(812, 577)
self.centralwidget = QtWidgets.QWidget(mainWindow)
self.centralwidget.setObjectName("centralwidget")
#Browse Button
self.browseButton = QtWidgets.QPushButton(self.centralwidget)
self.browseButton.setGeometry(QtCore.QRect(690, 480, 101, 61))
self.browseButton.setObjectName("browseButton")
#TextBrowser (big window)
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser.setGeometry(QtCore.QRect(20, 20, 581, 471))
self.textBrowser.setObjectName("textBrowser")
self.textBrowser.setFontFamily("monospace")
self.textBrowser.setFont(QtGui.QFont("monospace",11))
self.textBrowser.setOpenExternalLinks(True)
#Line Edit - small line for user input
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(20, 500, 581, 41))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.returnPressed.connect(self.run)
self.lineEdit.setPlaceholderText("Ask me anything...")
#Anton's Avatar
self.avatarLabel = QtWidgets.QLabel(self.centralwidget)
self.avatarLabel.setGeometry(QtCore.QRect(610, 20, 191, 251))
self.avatarLabel.setFrameShape(QtWidgets.QFrame.Box)
self.avatarLabel.setText("")
self.avatarLabel.setPixmap(QtGui.QPixmap("Anton.jpg"))
self.avatarLabel.setObjectName("avatarLabel")
#Send button and Yes/No Dialog
self.buttonBox = QtWidgets.QDialogButtonBox(self.centralwidget)
self.buttonBox.setGeometry(QtCore.QRect(400, 440, 193, 28))
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.sendButton = QtWidgets.QPushButton(self.centralwidget)
self.sendButton.setGeometry(QtCore.QRect(610, 480, 71, 61))
self.sendButton.setObjectName("sendButton")
self.sendButton.clicked.connect(self.run)
self.sendButton.clicked.connect(self.lineEdit.clear)
self.buttonBox.raise_()
self.browseButton.raise_()
self.textBrowser.raise_()
self.lineEdit.raise_()
self.avatarLabel.raise_()
self.sendButton.raise_()
mainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(mainWindow)
self.statusbar.setObjectName("statusbar")
mainWindow.setStatusBar(self.statusbar)
self.retranslateUi(mainWindow)
self.lineEdit.returnPressed.connect(self.lineEdit.clear)
self.sendButton.clicked.connect(self.lineEdit.copy)
QtCore.QMetaObject.connectSlotsByName(mainWindow)
def retranslateUi(self, mainWindow):
_translate = QtCore.QCoreApplication.translate
mainWindow.setWindowTitle(_translate("mainWindow", "Chatbot"))
self.textBrowser.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:7.8pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.sendButton.setText(_translate("mainWindow", "Send"))
def gettext(self): # Get text from user input text line
text = self.lineEdit.text()
return text
def answerr(self,text): # Print result to text browser
self.textBrowser.append(str(text))
def run(self):
#get user input
try:
userInput = self.gettext()
user = '<span style=\" color: #ff0000;\">%s</span>' % userInput
self.answerr("> "+user)
except (KeyboardInterrupt, EOFError) as e:
answerr("Bye!")
rec_video="https://www.youtube.com/watch?v=Z6MqOw2y744"
self.textBrowser.append("\nYou can find a video with the instructions on the link below.")
self.textBrowser.append(str("<a href=\""+rec_video+"\">'Youtube Link'</a>"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = QtWidgets.QMainWindow()
ui = Ui_mainWindow()
ui.setupUi(mainWindow)
mainWindow.show()
sys.exit(app.exec_())
如有任何帮助,我们将不胜感激。
P.S。如果我点击用户输入(红色字体),所有即将到来的聊天机器人响应也会变成红色。
我发现的唯一半解决方案是使用 QTextCursor.Start,但它会在每个问题后向上滚动。
问题是,当您单击 link 时,该格式被设置为当前格式,因此添加文本将使用该格式,一个可能的解决方案是将格式重置为它之前的值link 已按下(我已花时间使用布局改进您的示例)。
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.textbrowser = QtWidgets.QTextBrowser(openExternalLinks=True)
self.lineedit = QtWidgets.QLineEdit(
placeholderText=self.tr("Ask me anything...")
)
self.sendbutton = QtWidgets.QPushButton(self.tr("Send"))
self.browsebutton = QtWidgets.QPushButton()
self.avatarlabel = QtWidgets.QLabel(
frameShape=QtWidgets.QFrame.Box, pixmap=QtGui.QPixmap("Anton.jpg")
)
self.lineedit.setFixedHeight(40)
self.avatarlabel.setFixedSize(190, 250)
self.sendbutton.setFixedHeight(60)
self.browsebutton.setFixedHeight(60)
vlay_left = QtWidgets.QVBoxLayout()
vlay_right = QtWidgets.QVBoxLayout()
central_widget = QtWidgets.QWidget()
central_widget.setContentsMargins(10, 10, 10, 10)
self.setCentralWidget(central_widget)
hlay = QtWidgets.QHBoxLayout(central_widget)
hlay.addLayout(vlay_left)
hlay.addLayout(vlay_right)
vlay_left.addWidget(self.textbrowser)
vlay_left.addWidget(self.lineedit)
bottom_hlay = QtWidgets.QHBoxLayout()
bottom_hlay.addWidget(self.sendbutton)
bottom_hlay.addWidget(self.browsebutton)
vlay_right.addWidget(self.avatarlabel)
vlay_right.addStretch()
vlay_right.addLayout(bottom_hlay)
self.resize(640, 480)
self._text_format = self.textbrowser.currentCharFormat()
self.lineedit.returnPressed.connect(self.execute)
self.sendbutton.clicked.connect(self.lineedit.copy)
self.sendbutton.clicked.connect(self.execute)
self.textbrowser.setFontFamily("monospace")
self.textbrowser.setFont(QtGui.QFont("monospace", 11))
@property
def text_format(self):
return self._text_format
@text_format.setter
def text_format(self, fmt):
self._text_format = fmt
self.reset_format()
def reset_format(self):
self.textbrowser.setCurrentCharFormat(self.text_format)
@QtCore.pyqtSlot()
def execute(self):
self.reset_format()
text = self.lineedit.text()
user = '<span style=" color: #ff0000;">%s</span>' % text
self.answer("> " + user)
rec_video = "https://www.youtube.com/watch?v=Z6MqOw2y744"
self.textbrowser.append(
"\nYou can find a video with the instructions on the link below."
)
self.textbrowser.append('<a href="' + rec_video + "\">'Youtube Link'</a>")
self.lineedit.clear()
def answer(self, text):
self.textbrowser.append(text)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
我有一个奇怪的问题,我正在为聊天机器人创建 GUI,并且我选择了 PyQt5 Designer 来这样做。一切都运行良好,但现在我已经实现了一些 hyperlinks 并意识到当我在 QTextBrowser 中单击具有不同字体的行时,所有聊天机器人响应都会更改为该字体。 因此,例如,如果我单击 link,之后的每个答案都将被 hyperlinked.
代码片段:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_mainWindow(object):
def setupUi(self, mainWindow):
mainWindow.setObjectName("mainWindow")
mainWindow.resize(812, 577)
self.centralwidget = QtWidgets.QWidget(mainWindow)
self.centralwidget.setObjectName("centralwidget")
#Browse Button
self.browseButton = QtWidgets.QPushButton(self.centralwidget)
self.browseButton.setGeometry(QtCore.QRect(690, 480, 101, 61))
self.browseButton.setObjectName("browseButton")
#TextBrowser (big window)
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser.setGeometry(QtCore.QRect(20, 20, 581, 471))
self.textBrowser.setObjectName("textBrowser")
self.textBrowser.setFontFamily("monospace")
self.textBrowser.setFont(QtGui.QFont("monospace",11))
self.textBrowser.setOpenExternalLinks(True)
#Line Edit - small line for user input
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(20, 500, 581, 41))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.returnPressed.connect(self.run)
self.lineEdit.setPlaceholderText("Ask me anything...")
#Anton's Avatar
self.avatarLabel = QtWidgets.QLabel(self.centralwidget)
self.avatarLabel.setGeometry(QtCore.QRect(610, 20, 191, 251))
self.avatarLabel.setFrameShape(QtWidgets.QFrame.Box)
self.avatarLabel.setText("")
self.avatarLabel.setPixmap(QtGui.QPixmap("Anton.jpg"))
self.avatarLabel.setObjectName("avatarLabel")
#Send button and Yes/No Dialog
self.buttonBox = QtWidgets.QDialogButtonBox(self.centralwidget)
self.buttonBox.setGeometry(QtCore.QRect(400, 440, 193, 28))
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.sendButton = QtWidgets.QPushButton(self.centralwidget)
self.sendButton.setGeometry(QtCore.QRect(610, 480, 71, 61))
self.sendButton.setObjectName("sendButton")
self.sendButton.clicked.connect(self.run)
self.sendButton.clicked.connect(self.lineEdit.clear)
self.buttonBox.raise_()
self.browseButton.raise_()
self.textBrowser.raise_()
self.lineEdit.raise_()
self.avatarLabel.raise_()
self.sendButton.raise_()
mainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(mainWindow)
self.statusbar.setObjectName("statusbar")
mainWindow.setStatusBar(self.statusbar)
self.retranslateUi(mainWindow)
self.lineEdit.returnPressed.connect(self.lineEdit.clear)
self.sendButton.clicked.connect(self.lineEdit.copy)
QtCore.QMetaObject.connectSlotsByName(mainWindow)
def retranslateUi(self, mainWindow):
_translate = QtCore.QCoreApplication.translate
mainWindow.setWindowTitle(_translate("mainWindow", "Chatbot"))
self.textBrowser.setHtml(_translate("mainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:7.8pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.sendButton.setText(_translate("mainWindow", "Send"))
def gettext(self): # Get text from user input text line
text = self.lineEdit.text()
return text
def answerr(self,text): # Print result to text browser
self.textBrowser.append(str(text))
def run(self):
#get user input
try:
userInput = self.gettext()
user = '<span style=\" color: #ff0000;\">%s</span>' % userInput
self.answerr("> "+user)
except (KeyboardInterrupt, EOFError) as e:
answerr("Bye!")
rec_video="https://www.youtube.com/watch?v=Z6MqOw2y744"
self.textBrowser.append("\nYou can find a video with the instructions on the link below.")
self.textBrowser.append(str("<a href=\""+rec_video+"\">'Youtube Link'</a>"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = QtWidgets.QMainWindow()
ui = Ui_mainWindow()
ui.setupUi(mainWindow)
mainWindow.show()
sys.exit(app.exec_())
如有任何帮助,我们将不胜感激。 P.S。如果我点击用户输入(红色字体),所有即将到来的聊天机器人响应也会变成红色。 我发现的唯一半解决方案是使用 QTextCursor.Start,但它会在每个问题后向上滚动。
问题是,当您单击 link 时,该格式被设置为当前格式,因此添加文本将使用该格式,一个可能的解决方案是将格式重置为它之前的值link 已按下(我已花时间使用布局改进您的示例)。
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.textbrowser = QtWidgets.QTextBrowser(openExternalLinks=True)
self.lineedit = QtWidgets.QLineEdit(
placeholderText=self.tr("Ask me anything...")
)
self.sendbutton = QtWidgets.QPushButton(self.tr("Send"))
self.browsebutton = QtWidgets.QPushButton()
self.avatarlabel = QtWidgets.QLabel(
frameShape=QtWidgets.QFrame.Box, pixmap=QtGui.QPixmap("Anton.jpg")
)
self.lineedit.setFixedHeight(40)
self.avatarlabel.setFixedSize(190, 250)
self.sendbutton.setFixedHeight(60)
self.browsebutton.setFixedHeight(60)
vlay_left = QtWidgets.QVBoxLayout()
vlay_right = QtWidgets.QVBoxLayout()
central_widget = QtWidgets.QWidget()
central_widget.setContentsMargins(10, 10, 10, 10)
self.setCentralWidget(central_widget)
hlay = QtWidgets.QHBoxLayout(central_widget)
hlay.addLayout(vlay_left)
hlay.addLayout(vlay_right)
vlay_left.addWidget(self.textbrowser)
vlay_left.addWidget(self.lineedit)
bottom_hlay = QtWidgets.QHBoxLayout()
bottom_hlay.addWidget(self.sendbutton)
bottom_hlay.addWidget(self.browsebutton)
vlay_right.addWidget(self.avatarlabel)
vlay_right.addStretch()
vlay_right.addLayout(bottom_hlay)
self.resize(640, 480)
self._text_format = self.textbrowser.currentCharFormat()
self.lineedit.returnPressed.connect(self.execute)
self.sendbutton.clicked.connect(self.lineedit.copy)
self.sendbutton.clicked.connect(self.execute)
self.textbrowser.setFontFamily("monospace")
self.textbrowser.setFont(QtGui.QFont("monospace", 11))
@property
def text_format(self):
return self._text_format
@text_format.setter
def text_format(self, fmt):
self._text_format = fmt
self.reset_format()
def reset_format(self):
self.textbrowser.setCurrentCharFormat(self.text_format)
@QtCore.pyqtSlot()
def execute(self):
self.reset_format()
text = self.lineedit.text()
user = '<span style=" color: #ff0000;">%s</span>' % text
self.answer("> " + user)
rec_video = "https://www.youtube.com/watch?v=Z6MqOw2y744"
self.textbrowser.append(
"\nYou can find a video with the instructions on the link below."
)
self.textbrowser.append('<a href="' + rec_video + "\">'Youtube Link'</a>")
self.lineedit.clear()
def answer(self, text):
self.textbrowser.append(text)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())