使用 QtQuick.Controls 1.12 将 Qt TextTable 与 TextArea 一起使用时文本未对齐
Text gets missaligned when using Qt TextTable with TextArea using QtQuick.Controls 1.12
我在 Qml 中使用 TextArea 时遇到问题。 C++ 模型持有对该 TextArea 的引用。
当我在 C++ 模型中插入 QTextTable 时,一切正常,直到用户输入一些文本。在用户手动编辑几个单元格并在其中写入一些文本后,一切都变得一团糟。有人知道如何解决吗?
我还有一些其他功能运行良好。所以我猜c++模型和textarea之间的连接没有问题。
这里是Documenthandler.h
#include <QQuickTextDocument>
#include <QtGui/QTextCharFormat>
#include <QtCore/QTextCodec>
#include <qqmlfile.h>
QT_BEGIN_NAMESPACE
class QTextDocument;
QT_END_NAMESPACE
class DocumentHandler : public QObject
{
Q_OBJECT
Q_ENUMS(HAlignment)
Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
public:
DocumentHandler();
Q_INVOKABLE void createTable(int columns ,int rows);
QQuickItem *target() { return m_target; }
void setTarget(QQuickItem *target);
QString text() const;
public Q_SLOTS:
void setText(const QString &arg);
Q_SIGNALS:
void targetChanged();
void textChanged();
void error(QString message);
private:
QTextCursor textCursor() const;
QQuickItem *m_target;
QTextDocument *m_doc;
QString m_text;
};
这是documenthandler.cpp
在“createTable”函数中,我创建了 table
#include "documenthandler.h"
#include <QtGui/QTextDocument>
#include <QtGui/QTextList>
#include <QtGui/QTextTable>
#include <QtGui/QTextCursor>
#include <QtGui/QFontDatabase>
#include <QtCore/QFileInfo>
DocumentHandler::DocumentHandler()
: m_target(0)
, m_doc(0)
{
}
void DocumentHandler::setTarget(QQuickItem *target)
{
m_doc = 0;
m_target = target;
if (!m_target)
return;
QVariant doc = m_target->property("textDocument");
if (doc.canConvert<QQuickTextDocument*>()) {
QQuickTextDocument *qqdoc = doc.value<QQuickTextDocument*>();
if (qqdoc)
m_doc = qqdoc->textDocument();
}
emit targetChanged();
}
void DocumentHandler::setText(const QString &arg)
{
if (m_text != arg) {
m_text = arg;
emit textChanged();
}
}
QString DocumentHandler::text() const
{
return m_text;
}
QTextCursor DocumentHandler::textCursor() const
{
if (!m_doc)
return QTextCursor();
QTextCursor cursor = QTextCursor(m_doc);
return cursor;
}
void DocumentHandler::createTable(int columns , int rows)
{
QTextCursor cursor = textCursor();
if (cursor.isNull())
return;
cursor.insertTable(rows,columns);
}
这里是主要的qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.6
import DocumentHandler 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Button
{
id:btn
text:"test"
onClicked: document.createTable(5,5);
}
TextArea {
Accessible.name: "document"
id: tooltip_area
selectByMouse: true
anchors.left:parent.left
anchors.right:parent.right
anchors.top: btn.bottom
anchors.bottom: parent.bottom
baseUrl: "qrc:/"
text: document.text
textFormat: Qt.RichText
wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
Component.onCompleted: forceActiveFocus()
}
DocumentHandler{
id: document
target: tooltip_area
}
}
这里是主要功能,除了我注册了QML Type之外没有什么特别的
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "documenthandler.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
qmlRegisterType<DocumentHandler>("DocumentHandler",1,0,"DocumentHandler");
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
这是填满一些单元格后的样子
所以我通过选择所有内容并在文本更改时取消选择来解决了这个问题。理论上我只需要在 Table 块中时才需要这样做。
onTextChanged:
{
if(recoursionlock)
{
recoursionlock =false;
var curpos = tooltip_area.cursorPosition;
var select_start = tooltip_area.selectionStart;
var select_end = tooltip_area.selectionEnd;
selectAll();
deselect();
if(curpos !== -1 && curpos >= tooltip_area.text.lenght)
tooltip_area.cursorPosition = curpos;
else
tooltip_area.select(select_start,select_end)
recoursionlock = true;
}
}
我在 Qml 中使用 TextArea 时遇到问题。 C++ 模型持有对该 TextArea 的引用。 当我在 C++ 模型中插入 QTextTable 时,一切正常,直到用户输入一些文本。在用户手动编辑几个单元格并在其中写入一些文本后,一切都变得一团糟。有人知道如何解决吗?
我还有一些其他功能运行良好。所以我猜c++模型和textarea之间的连接没有问题。
这里是Documenthandler.h
#include <QQuickTextDocument>
#include <QtGui/QTextCharFormat>
#include <QtCore/QTextCodec>
#include <qqmlfile.h>
QT_BEGIN_NAMESPACE
class QTextDocument;
QT_END_NAMESPACE
class DocumentHandler : public QObject
{
Q_OBJECT
Q_ENUMS(HAlignment)
Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
public:
DocumentHandler();
Q_INVOKABLE void createTable(int columns ,int rows);
QQuickItem *target() { return m_target; }
void setTarget(QQuickItem *target);
QString text() const;
public Q_SLOTS:
void setText(const QString &arg);
Q_SIGNALS:
void targetChanged();
void textChanged();
void error(QString message);
private:
QTextCursor textCursor() const;
QQuickItem *m_target;
QTextDocument *m_doc;
QString m_text;
};
这是documenthandler.cpp 在“createTable”函数中,我创建了 table
#include "documenthandler.h"
#include <QtGui/QTextDocument>
#include <QtGui/QTextList>
#include <QtGui/QTextTable>
#include <QtGui/QTextCursor>
#include <QtGui/QFontDatabase>
#include <QtCore/QFileInfo>
DocumentHandler::DocumentHandler()
: m_target(0)
, m_doc(0)
{
}
void DocumentHandler::setTarget(QQuickItem *target)
{
m_doc = 0;
m_target = target;
if (!m_target)
return;
QVariant doc = m_target->property("textDocument");
if (doc.canConvert<QQuickTextDocument*>()) {
QQuickTextDocument *qqdoc = doc.value<QQuickTextDocument*>();
if (qqdoc)
m_doc = qqdoc->textDocument();
}
emit targetChanged();
}
void DocumentHandler::setText(const QString &arg)
{
if (m_text != arg) {
m_text = arg;
emit textChanged();
}
}
QString DocumentHandler::text() const
{
return m_text;
}
QTextCursor DocumentHandler::textCursor() const
{
if (!m_doc)
return QTextCursor();
QTextCursor cursor = QTextCursor(m_doc);
return cursor;
}
void DocumentHandler::createTable(int columns , int rows)
{
QTextCursor cursor = textCursor();
if (cursor.isNull())
return;
cursor.insertTable(rows,columns);
}
这里是主要的qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.6
import DocumentHandler 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Button
{
id:btn
text:"test"
onClicked: document.createTable(5,5);
}
TextArea {
Accessible.name: "document"
id: tooltip_area
selectByMouse: true
anchors.left:parent.left
anchors.right:parent.right
anchors.top: btn.bottom
anchors.bottom: parent.bottom
baseUrl: "qrc:/"
text: document.text
textFormat: Qt.RichText
wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
Component.onCompleted: forceActiveFocus()
}
DocumentHandler{
id: document
target: tooltip_area
}
}
这里是主要功能,除了我注册了QML Type之外没有什么特别的
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "documenthandler.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
qmlRegisterType<DocumentHandler>("DocumentHandler",1,0,"DocumentHandler");
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
这是填满一些单元格后的样子
所以我通过选择所有内容并在文本更改时取消选择来解决了这个问题。理论上我只需要在 Table 块中时才需要这样做。
onTextChanged:
{
if(recoursionlock)
{
recoursionlock =false;
var curpos = tooltip_area.cursorPosition;
var select_start = tooltip_area.selectionStart;
var select_end = tooltip_area.selectionEnd;
selectAll();
deselect();
if(curpos !== -1 && curpos >= tooltip_area.text.lenght)
tooltip_area.cursorPosition = curpos;
else
tooltip_area.select(select_start,select_end)
recoursionlock = true;
}
}