Pyside6。 qtextblock.qtextlayout.setformats
如何使用setFormats
?
程序显示qtextedit
in qmainwindow
。
任务是找到“导入”一词,并在红色中使用block.lob.setformats
(我不希望撤消redo历史记录到包括外观变化,我不想使用QSyntaxHighlighter )。
我不明白为什么在找到“导入”一词然后setFormats
时,相应的块变得不可见。
from PySide6 import QtWidgets, QtCore, QtGui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.central_widget = QtWidgets.QWidget(self)
self.central_widget.setLayout(QtWidgets.QVBoxLayout(self.central_widget))
self.text_editor = QtWidgets.QTextEdit(self.central_widget)
self.central_widget.layout().addWidget(self.text_editor)
self.setCentralWidget(self.central_widget)
self.text_editor.setFont(QtGui.QFont('Arial', 14))
self.text_editor.textChanged.connect(self.text_changed)
@QtCore.Slot()
def text_changed(self):
word = 'import'
text_cursor_before_find_op = self.text_editor.textCursor()
self.text_editor.moveCursor(QtGui.QTextCursor.MoveOperation.Start)
found = self.text_editor.find(word)
if found:
text_cursor = self.text_editor.textCursor()
text_cursor.setPosition(text_cursor.position())
block = text_cursor.block()
position_in_block = text_cursor.positionInBlock() - len(word)
format_range = QtGui.QTextLayout.FormatRange()
format_range.start = position_in_block
format_range.length = len(word)
format_range.format = self.text_editor.currentCharFormat()
format_range.format.setForeground(QtGui.QColor('#FF0000'))
formats = [format_range]
block.layout().setFormats(formats)
print(position_in_block,
repr(block.text()),
(format_range.start, format_range.length, format_range.format),
block.isValid(), block.isVisible(),
sep='\n', end='\n\n')
self.text_editor.setTextCursor(text_cursor_before_find_op)
app = QtWidgets.QApplication()
window = MainWindow()
window.show()
app.exec()
How to work with setFormats
?
The program displays QTextEdit
in QMainWindow
.
The task is to find the word "import" and highlight it in red using block.layout.setFormats
(I don't want the undo-redo history to include the appearance change, and I don't want to use QSyntaxHighlighter).
I don't understand why when finding the word "import" and then setFormats
, the corresponding block becomes invisible.
from PySide6 import QtWidgets, QtCore, QtGui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.central_widget = QtWidgets.QWidget(self)
self.central_widget.setLayout(QtWidgets.QVBoxLayout(self.central_widget))
self.text_editor = QtWidgets.QTextEdit(self.central_widget)
self.central_widget.layout().addWidget(self.text_editor)
self.setCentralWidget(self.central_widget)
self.text_editor.setFont(QtGui.QFont('Arial', 14))
self.text_editor.textChanged.connect(self.text_changed)
@QtCore.Slot()
def text_changed(self):
word = 'import'
text_cursor_before_find_op = self.text_editor.textCursor()
self.text_editor.moveCursor(QtGui.QTextCursor.MoveOperation.Start)
found = self.text_editor.find(word)
if found:
text_cursor = self.text_editor.textCursor()
text_cursor.setPosition(text_cursor.position())
block = text_cursor.block()
position_in_block = text_cursor.positionInBlock() - len(word)
format_range = QtGui.QTextLayout.FormatRange()
format_range.start = position_in_block
format_range.length = len(word)
format_range.format = self.text_editor.currentCharFormat()
format_range.format.setForeground(QtGui.QColor('#FF0000'))
formats = [format_range]
block.layout().setFormats(formats)
print(position_in_block,
repr(block.text()),
(format_range.start, format_range.length, format_range.format),
block.isValid(), block.isVisible(),
sep='\n', end='\n\n')
self.text_editor.setTextCursor(text_cursor_before_find_op)
app = QtWidgets.QApplication()
window = MainWindow()
window.show()
app.exec()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道为什么
block.layout.setformats()
不起作用。但是,如果您的目的是突出显示“导入”一词,那么您可能需要使用类似的东西。
当然,这有一些局限性,例如,仅查找整个文档中的第一次出现,而不是检查单词是否由Whitespace界定,在将单词更改为其他内容等之后保持格式。但是您需要自己解决这些问题。您的原始Coude将具有相同的限制。
I have no idea why
block.layout.setFormats()
does not work.But if your intention is to highlight the word "import", then you might want to use something like this.
Of course this has some limitations, e.g. finding only the first occurrence in the whole document, not checking if the word is delimited by whitespace, keeping format after changing the word to something else etc. But you will need to resolve these yourself. Your original coude would have the same limitations.
我认为这是一种错误。
在其他版本中,在Setadditionalformats的时代,我本可以毫无问题地为文本着色。
我执行了您的代码,并输入了“导入”。似乎没有调用块上的绘制函数(qtextlayout.draw函数),因为光标来停止闪烁。
qtextlayout.formatrange通常用于
qabstractTextDocumentLayout
的绘制函数。和光标(qtextlayout.drawcursor函数)在同一函数中绘制。qtextlayout
具有绘制功能,并且在该功能中也使用了功能。This drawing seems that it doesn't work well by some reasons.
(I assume that
setFormats
is related to something flags).无论如何,我发现我们可以通过通过鼠标手柄水平扩展文本deDEDIT的大小来避免此错误。
但这不是很好,我们使用鼠标句柄一一使用,我使用
qtextedit
的resizeevent。如果我们垂直扩大尺寸,这效果不佳。我不知道为什么...resizeevent
具有调用重新粉刷的副作用。但是,如果我直接使用RepAlt()函数,则不会发生重新粉刷...我不知道为什么...无论如何,我认为这个问题是一种QT错误。I think this is a kind of bug.
In other version, in the era of setAdditionalFormats, I could have colorized the text without problem.
I executed your code, and typed "import". It seemed that the draw function on the block(QTextLayout.draw function) isn't be called, since the cursor came to stop blinking.
QTextLayout.FormatRange is usually used in a draw function of
QAbstractTextDocumentLayout
. And cursor(QTextLayout.drawCursor function) is drawn in the same function.QTextLayout
has draw function and this is also used in that function.This drawing seems that it doesn't work well by some reasons.
(I assume that
setFormats
is related to something flags).At any rate, I found out that we can avoid this bug by expanding the size of textedit horizontally by mouse handle.
But it is not good we use mouse handle one by one, I use resizeEvent of
QTextEdit
. this doesn't work well if we expand the size vertically. I don't know why...resizeEvent
have a side effect of invoking repainting. But if I use repaint() function directly, repaint is not happend... I don't know why... Anyway, I think this problem is a kind of Qt bug.