如何获取 QTextTableCell 的边界框
How to get boundingBox of a QTextTableCell
我正在使用 QTextDocument 并需要进行一些自定义命中测试,为此我需要找到 QTextTableCell 的边界框但找不到任何方法来解决它。有人可以就我应该如何获得它提出一些建议或任何想法。
我发现在不对 Qt 代码进行任何更改的情况下无论如何都无法做到这一点,这是我必须做的事情的不同之处。
==== //local/qt5/qtbase/src/gui/text/qabstracttextdocumentlayout.h#2 (text) ====
@@ -92,6 +92,11 @@
virtual QRectF frameBoundingRect(QTextFrame *frame) const = 0;
virtual QRectF blockBoundingRect(const QTextBlock &block) const = 0;
+ virtual QRectF cellBoundingRect(QTextTable &table, const QTextTableCell &cell) const
+ {
+ return QRectF();
+ }
+
void setPaintDevice(QPaintDevice *device);
QPaintDevice *paintDevice() const;
==== //local/qt5/qtbase/src/gui/text/qtextdocumentlayout.cpp#3 (text) ====
@@ -3201,6 +3201,17 @@
return QRectF(pos, data(table)->size.toSizeF());
}
+QRectF QTextDocumentLayout::cellBoundingRect( QTextTable &table, const QTextTableCell &cell) const
+{
+ Q_D(const QTextDocumentLayout);
+ if (d->docPrivate->pageSize.isNull())
+ return QRectF();
+ d->ensureLayoutFinished();
+ QTextTableData *td = static_cast(data(&table));
+ QRectF cellRect = td->cellRect(cell);
+ return cellRect;
+}
+
QRectF QTextDocumentLayout::frameBoundingRect(QTextFrame *frame) const
{
Q_D(const QTextDocumentLayout);
==== //local/qt5/qtbase/src/gui/text/qtextdocumentlayout_p.h#1 (text) ====
@@ -104,6 +104,8 @@
bool contentHasAlignment() const;
+ virtual QRectF cellBoundingRect(QTextTable &table, const QTextTableCell &cell) const;
+
protected:
void documentChanged(int from, int oldLength, int length);
void resizeInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format);
实际上有一种方法可以获得单元格的矩形。您需要遍历单元格内容并加入这些区域。最后添加单元格的填充。这是一个工作示例。但如果您的单元格包含嵌套框架或跨多行的单元格,您可能必须扩展它。
QRectF cellBounds(QTextEdit& edit, QTextTable& table, QTextTableCell& cell, bool rowCheck = true) {
QTextTableFormat tableFormat = table.format();
qreal cellExtra = tableFormat.cellPadding() /* + tableFormat.border()*/;
int vOffset = edit.verticalScrollBar()->value();
QTextBlock next = cell.firstCursorPosition().block();
QTextBlock last = cell.lastCursorPosition().block();
QAbstractTextDocumentLayout* layout = edit.document()->documentLayout();
QRectF bounds;
while (next.isValid()) {
bounds = bounds.isNull() ? layout->blockBoundingRect(next) : bounds.united(layout->blockBoundingRect(next));
if (next == last) {
break;
}
next = next.next();
}
if (!bounds.isNull()) {
bounds.adjust(-cellExtra, -cellExtra, cellExtra, cellExtra);
bounds.translate(0, -vOffset);
if(rowCheck) {
for(int col = 0; col < table.columns(); col++) {
if(col != cell.column()) {
QTextTableCell nextCell = table.cellAt(cell.row(), col);
QRectF nextBounds = cellBounds(edit, table, nextCell, false);
if(nextBounds.height() > bounds.height())
bounds.setHeight(nextBounds.height());
}
}
}
}
return bounds;
}
我正在使用 QTextDocument 并需要进行一些自定义命中测试,为此我需要找到 QTextTableCell 的边界框但找不到任何方法来解决它。有人可以就我应该如何获得它提出一些建议或任何想法。
我发现在不对 Qt 代码进行任何更改的情况下无论如何都无法做到这一点,这是我必须做的事情的不同之处。
==== //local/qt5/qtbase/src/gui/text/qabstracttextdocumentlayout.h#2 (text) ==== @@ -92,6 +92,11 @@ virtual QRectF frameBoundingRect(QTextFrame *frame) const = 0; virtual QRectF blockBoundingRect(const QTextBlock &block) const = 0; + virtual QRectF cellBoundingRect(QTextTable &table, const QTextTableCell &cell) const + { + return QRectF(); + } + void setPaintDevice(QPaintDevice *device); QPaintDevice *paintDevice() const; ==== //local/qt5/qtbase/src/gui/text/qtextdocumentlayout.cpp#3 (text) ==== @@ -3201,6 +3201,17 @@ return QRectF(pos, data(table)->size.toSizeF()); } +QRectF QTextDocumentLayout::cellBoundingRect( QTextTable &table, const QTextTableCell &cell) const +{ + Q_D(const QTextDocumentLayout); + if (d->docPrivate->pageSize.isNull()) + return QRectF(); + d->ensureLayoutFinished(); + QTextTableData *td = static_cast(data(&table)); + QRectF cellRect = td->cellRect(cell); + return cellRect; +} + QRectF QTextDocumentLayout::frameBoundingRect(QTextFrame *frame) const { Q_D(const QTextDocumentLayout); ==== //local/qt5/qtbase/src/gui/text/qtextdocumentlayout_p.h#1 (text) ==== @@ -104,6 +104,8 @@ bool contentHasAlignment() const; + virtual QRectF cellBoundingRect(QTextTable &table, const QTextTableCell &cell) const; + protected: void documentChanged(int from, int oldLength, int length); void resizeInlineObject(QTextInlineObject item, int posInDocument, const QTextFormat &format);
实际上有一种方法可以获得单元格的矩形。您需要遍历单元格内容并加入这些区域。最后添加单元格的填充。这是一个工作示例。但如果您的单元格包含嵌套框架或跨多行的单元格,您可能必须扩展它。
QRectF cellBounds(QTextEdit& edit, QTextTable& table, QTextTableCell& cell, bool rowCheck = true) {
QTextTableFormat tableFormat = table.format();
qreal cellExtra = tableFormat.cellPadding() /* + tableFormat.border()*/;
int vOffset = edit.verticalScrollBar()->value();
QTextBlock next = cell.firstCursorPosition().block();
QTextBlock last = cell.lastCursorPosition().block();
QAbstractTextDocumentLayout* layout = edit.document()->documentLayout();
QRectF bounds;
while (next.isValid()) {
bounds = bounds.isNull() ? layout->blockBoundingRect(next) : bounds.united(layout->blockBoundingRect(next));
if (next == last) {
break;
}
next = next.next();
}
if (!bounds.isNull()) {
bounds.adjust(-cellExtra, -cellExtra, cellExtra, cellExtra);
bounds.translate(0, -vOffset);
if(rowCheck) {
for(int col = 0; col < table.columns(); col++) {
if(col != cell.column()) {
QTextTableCell nextCell = table.cellAt(cell.row(), col);
QRectF nextBounds = cellBounds(edit, table, nextCell, false);
if(nextBounds.height() > bounds.height())
bounds.setHeight(nextBounds.height());
}
}
}
}
return bounds;
}