qtextDocument和选择绘画

发布于 2025-01-25 17:53:46 字数 1948 浏览 1 评论 0原文

我正在用qtextDocument :: drawcontents在小部件上画一块文本。我目前的目标是拦截鼠标事件并模拟文本选择。很明显如何处理鼠标,但是显示结果使我感到困惑很多。

就在我们开始之前:我无法使用Qlabel并让它自行处理选择(它不知道如何绘制异常的字符和混乱线高度( https://git.macaw.me/blue/blue/squawk/issues/59 ))泡泡,我还没有准备在那里牺牲表演。

在QTEXTDOCUMENT上有一个非常丰富的框架,但是我找不到任何方法使其与我认为选择的一些文本片段的背景着色。找到了一种围绕文本制作框架的方法,找到了一种绘制衬里文本的方法,但是看起来这个框架根本无法在文本背后绘制背景。

我已经尝试这样做,看看是否可以在某些QTEXTFRAME下进行选定的片段,并设置它的样式:

QTextDocument* bodyRenderer = new QTextDocument();
bodyRenderer->setHtml("some text");
bodyRenderer->setTextWidth(50);
painter->setBackgroundMode(Qt::BGMode::OpaqueMode); //this at least makes it color background under all text
QTextFrameFormat format = bodyRenderer->rootFrame()->frameFormat();
format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
bodyRenderer->rootFrame()->setFrameFormat(format);
bodyRenderer->drawContents(painter);

也没有任何作用:

QTextBlock b = bodyRenderer->begin();
QTextBlockFormat format = b.blockFormat();
format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
format.setProperty(QTextFormat::BackgroundBrush, option.palette.brush(QPalette::Active, QPalette::Highlight));
QTextCursor cursor(bodyRenderer);
cursor.setBlockFormat(format);
b = bodyRenderer->begin();
while (b.isValid() > 0) {
    QTextLayout* lay = b.layout();
    QTextLayout::FormatRange range;
    range.format = b.charFormat();
    range.start = 0;
    range.length = 2;
    lay->draw(painter, option.rect.topLeft(), {range});
    b = b.next();
}

有什么方法可以使我可以使此框架做一个简单的事情 - 绘制一些文本背后的选择背景?如果没有 - 有没有办法可以将光标位置放在坐标转换中,就像我可以从qabstracttextDocumentLayout :: HittestqabstracttextDocumentLayout :: from verse Operation只是为了了解自己在哪里绘制选择矩形的位置吗?

I am painting a block of text on a widget with QTextDocument::drawContents. My current goal is to intercept mouse events and emulate text selection. It's pretty clear how to handle the mouse, but displaying the result puzzles me a lot.

Just before we start: I can not use QLabel and let it handle selection on it's own (it has no idea how to draw unusual characters and messes up line height (https://git.macaw.me/blue/squawk/issues/59)), nor I can not use QTextBrowser there - it's just a message bubble, I'm not ready to sacrifice performance there.

There is a very rich framework around QTextDocument, but I can not find any way to make it color the background of some fragment of text that I would consider selected. Found a way to make a frame around a text, found a way to draw under-over-lined text, but it looks like there is simply just no way this framework can draw a background behind text.

I have tried doing this, to see if I can take selected fragment under some QTextFrame and set it's style:

QTextDocument* bodyRenderer = new QTextDocument();
bodyRenderer->setHtml("some text");
bodyRenderer->setTextWidth(50);
painter->setBackgroundMode(Qt::BGMode::OpaqueMode); //this at least makes it color background under all text
QTextFrameFormat format = bodyRenderer->rootFrame()->frameFormat();
format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
bodyRenderer->rootFrame()->setFrameFormat(format);
bodyRenderer->drawContents(painter);

Nothing of this works too:

QTextBlock b = bodyRenderer->begin();
QTextBlockFormat format = b.blockFormat();
format.setBackground(option.palette.brush(QPalette::Active, QPalette::Highlight));
format.setProperty(QTextFormat::BackgroundBrush, option.palette.brush(QPalette::Active, QPalette::Highlight));
QTextCursor cursor(bodyRenderer);
cursor.setBlockFormat(format);
b = bodyRenderer->begin();
while (b.isValid() > 0) {
    QTextLayout* lay = b.layout();
    QTextLayout::FormatRange range;
    range.format = b.charFormat();
    range.start = 0;
    range.length = 2;
    lay->draw(painter, option.rect.topLeft(), {range});
    b = b.next();
}

Is there any way I can make this framework do a simple thing - draw a selection background behind some text? If not - is there a way I can unproject cursor position into coordinate translation, like can I do reverse operation from QAbstractTextDocumentLayout::hitTest just to understand where to draw that selection rectangle myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼泪淡了忧伤 2025-02-01 17:53:47

您可以使用qtextcursor来更改所选文本的背景。您只需要一次选择一个字符即可保持格式。这是突出显示为蓝色的一个示例(文本的颜色以白色突出显示为对比):

void MainWindow::paintEvent(QPaintEvent *event) {
  QPainter painter(this);
  painter.fillRect(contentsRect(), QBrush(QColor("white")));
  QTextDocument document;
  document.setHtml(QString("Hello <font size='20'>world</font> with Qt!"));

  int selectionStart = 3;
  int selectionEnd = selectionStart + 10;
  QTextCursor cursor(&document);
  cursor.setPosition(selectionStart);
  while (cursor.position() < selectionEnd) {
    cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); // select one symbol
    QTextCharFormat selectFormat = cursor.charFormat();
    selectFormat.setBackground(Qt::blue);
    selectFormat.setForeground(Qt::white);
    cursor.setCharFormat(selectFormat);                                // set format for selection
    cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
  }

  document.drawContents(&painter, contentsRect());
  QMainWindow::paintEvent(event);
}

You can use QTextCursor to change the background of the selected text. You only need to select one character at a time to keep the formatting. Here is an example of highlighting in blue (the color of the text is highlighted in white for contrast):

void MainWindow::paintEvent(QPaintEvent *event) {
  QPainter painter(this);
  painter.fillRect(contentsRect(), QBrush(QColor("white")));
  QTextDocument document;
  document.setHtml(QString("Hello <font size='20'>world</font> with Qt!"));

  int selectionStart = 3;
  int selectionEnd = selectionStart + 10;
  QTextCursor cursor(&document);
  cursor.setPosition(selectionStart);
  while (cursor.position() < selectionEnd) {
    cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); // select one symbol
    QTextCharFormat selectFormat = cursor.charFormat();
    selectFormat.setBackground(Qt::blue);
    selectFormat.setForeground(Qt::white);
    cursor.setCharFormat(selectFormat);                                // set format for selection
    cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
  }

  document.drawContents(&painter, contentsRect());
  QMainWindow::paintEvent(event);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文