QTextEdit个人使用心得(二)

接上篇文章,第一篇文章实现了几个常用的操作。这篇文章要说的是QTextEdit的复制粘贴等操作,个人认为这才是自定义数据在QTextEdit控件中操作的难点,因为要保证自定义数据的完整性和准确性。下面我们就来看一下自定义数据的复制粘贴。

  • 首先我们要定义一个我们自己数据的格式,我这里声明了一些结构体
enum DataType
{
    Type_Text = 0, //普通文本
    Type_EmojiCode,//表情码
    Type_Br,       //换行符"\n"
    Type_HyperLinkText, //超链接文本

    /***当前编辑框使用***/
    Type_EmojiImage,//表情图片
    Type_File,//文件
    Type_ScreenImage,//截图
    /*****************/

    Type_Default   //默认
};

struct sSingleDataInfo //单条数据信息
{
    QVariant m_var; //数据
    DataType m_type; //数据类型

    sSingleDataInfo()
    {
        m_type = Type_Default;
    }

    sSingleDataInfo(const sSingleDataInfo &parm)
    {
        this->m_var = parm.m_var;
        this->m_type = parm.m_type;
    }

    sSingleDataInfo &operator=(const sSingleDataInfo &parm)
    {
        if (this == &parm)
        {
            return *this;
        }
        this->m_var = parm.m_var;
        this->m_type  = parm.m_type;
        return *this;
    }

    void clear()
    {
        m_var.clear();
        m_type = Type_Default;
    }
};

struct sSingleCopyInfo //单个数据复制信息
{
    QString m_var; //数据
    int m_type; //数据类型

    sSingleCopyInfo()
    {
        m_type = (int)Type_Default;
    }

    sSingleCopyInfo(const sSingleCopyInfo &parm)
    {
        this->m_var = parm.m_var;
        this->m_type = parm.m_type;
    }

    sSingleCopyInfo &operator=(const sSingleCopyInfo &parm)
    {
        if (this == &parm)
        {
            return *this;
        }
        this->m_var = parm.m_var;
        this->m_type  = parm.m_type;
        return *this;
    }

    void clear()
    {
        m_var.clear();
        m_type = (int)Type_Default;
    }
};

Q_DECLARE_METATYPE(sSingleCopyInfo)

当我们输入了自定义数据时,如图:在进行复制操作。如下

void EditDrop::slotcopy()
{
    QTextDocumentFragment DocumentFragment = this->textCursor().selection();
    CopyEditDataToClipboard(FormatProcessData(DocumentFragment));//处理自定义数据接口
}
/*!
 * \brief 格式化处理在编辑框复制的数据
 * \param DocumentFragment 需要格式化处理的数据
 * \param RecoveryData 该字段表示在编辑框恢复上次的数据(例如回退、前进)的标记,默认为false。
 */
QList<sSingleCopyInfo> EditDrop::FormatProcessData(QTextDocumentFragment DocumentFragment, bool RecoveryData)
{
    QTextEdit* TempTextEdit = new QTextEdit;
    m_filePathList.clear();
    TempTextEdit->textCursor().insertFragment(DocumentFragment);

    QTextDocument* TextDocument  = TempTextEdit->document();
    QTextFrame* TextFrame        = TextDocument->rootFrame();
    QTextFrame::Iterator frameIt = TextFrame->begin();

    QString strText = "";
    QList<sSingleCopyInfo> DataList;

    for (QTextFrame::Iterator it = frameIt;
         !it.atEnd();)
    {
        if (it.currentBlock().isValid())
        {
            const QTextBlock block = it.currentBlock();
            QTextBlock::Iterator it_1 = block.begin();
            for (; !it_1.atEnd(); ++it_1)
            {
                const QTextFragment fragment = it_1.fragment();
                const QTextCharFormat format = fragment.charFormat();
                QString txt = fragment.text();
                const bool isObject = txt.contains(QChar::ObjectReplacementCharacter);
                const bool isImage  = isObject && format.isImageFormat();
                if (isObject)
                {
                    for(int i = 0; isImage && i < txt.length(); ++i)
                    {
                        QTextImageFormat imgFmt = format.toImageFormat();
                        QString name = imgFmt.name();

                        if(name.contains("dropped_image_"))
                        {
                            QUrl url = QUrl::fromLocalFile(name);
                            name = url.toLocalFile();

                            strLength = strLength + 1;
                            sSingleCopyInfo info;
                            info.m_var = name;
                            info.m_type = Type_ScreenImage;
                            DataList.append(info);
                            if(RecoveryData)
                            {
                              QUrl tempxx = QUrl::fromLocalFile(name);
                              m_hash_Path[tempxx.toLocalFile()] = tempxx.toLocalFile();
                              m_filePathList.append(tempxx.toLocalFile());
                            }
                        }
                        else if(name.contains("EmojiImagesBig"))
                        {
                            strLength = strLength + 1;
                            sSingleCopyInfo info;
                            info.m_var = name;
                            info.m_type = Type_EmojiImage;
                            DataList.append(info);
                            if(RecoveryData)
                            {
                              m_list_emoji.append(name);
                            }
                        }
                        else
                        {
                            QUrl url = QUrl::fromLocalFile(name);
                            name = url.toLocalFile();

                            strLength = strLength + 1;
                            sSingleCopyInfo info;
                            info.m_var = name;
                            info.m_type = Type_File;
                            DataList.append(info);
                            if(RecoveryData && info.m_type == Type_File)
                            {
                                m_hash_Path[name] = name;
                                QUrl tempxx = QUrl::fromLocalFile(name);
                                m_hash_Path[tempxx.toLocalFile()] = tempxx.toLocalFile();
                                m_filePathList.append(tempxx.toLocalFile());
                            }
                        }
                    }
                    continue;
                }
                strLength = strLength + txt.length();
                sSingleCopyInfo info;
                info.m_var = txt;
                info.m_type = Type_Text;
                DataList.append(info);
            }

            ++it;
            if(!it.atEnd())
            {
                strLength = strLength + 1;
                strText.append("\n");
                sSingleCopyInfo info;
                info.m_var = "\n";
                info.m_type = Type_Br;
                DataList.append(info);
            }
            continue;
        }
        ++it;
    }
    return DataList;
}
/*!
 * \brief 把编辑框复制的数据复制到系统剪切板
 * \param copyInfoList 数据结构体
 */
void EditDrop::CopyEditDataToClipboard(QList<sSingleCopyInfo> copyInfoList)
{
    QString dataStr = "";
    foreach (sSingleCopyInfo varData, copyInfoList)
    {
        //普通文本
        if (varData.m_type == Type_Text)
        {
            dataStr += varData.m_var;
        }
    }

    //将复制的所有文本字符构成的字符串设到剪切板
    QClipboard *pBoard = QApplication::clipboard();
    if(nullptr== pBoard)
    {
        return;
    }

    //将复制的所有内容设置到剪切板
    QMimeData *pCusData = new QMimeData();//自定义数据
    QByteArray dataArray = getSingleCopyInfoListSerialize(copyInfoList);
    pCusData->setData("EditText", dataArray);
    pCusData->setData(QString("text/plain"), dataStr.toUtf8());
    pBoard->setMimeData(pCusData);
}

粘贴自定义数据:

/*!
 * \brief 处理编辑框自定义粘贴内容
 * \return
 */
bool EditDrop::dealEditTextContentPaste()
{
    bool bDeal = false;
    QClipboard *pBoard = QApplication::clipboard();
    if(nullptr == pBoard)
    {
        return bDeal;
    }

    QString qDebugStr = QString("");

    const QMimeData *pMimeData = pBoard->mimeData();
    if(pMimeData && pMimeData->hasFormat("EditText"))
    {
        bDeal = true;
        QByteArray array = pMimeData->data("EditText");
        QList<sSingleCopyInfo> copyInfoList = getSingleCopyInfoListDeserialize(array);

        foreach (sSingleCopyInfo copyInfo, copyInfoList)
        {
            qDebugStr += copyInfo.m_var;

            QString strValue = copyInfo.m_var;
            switch ((DataType)copyInfo.m_type)
            {
            case Type_Text:
            {
                this->textCursor().insertText(strValue);
            }break;
            case Type_EmojiImage:
            {
                SetEmojiPath(strValue);
                m_list_emoji.append(strValue);
            }break;
            case Type_ScreenImage:
            {
                ProcessEditTextImage(strValue);
            }break;
            case Type_File:
            {
                SetEditImage(strValue);
            }break;
            case Type_Br:
            {
                this->textCursor().insertText("\n");
            }break;

            default:
                break;
            }
        }

        //qDebug() << tr("粘贴内容: %1").arg(qDebugStr);
    }

    return bDeal;
}

复制时需要把我们自定义的格式序列化后传递给系统剪切板,粘贴时把剪切板数据反序列化回来解析到界面。

 总结


QTextEdit的自定义数据的处理难点个人认为在数据的解析和处理上(大佬轻喷)。还需对QTextEdit内部对数据处理和存储有初步的认识以及对QT中文档相关类和xml处理解析类的数据存储结构和处理逻辑有初步的认识,俗话说知己知彼才能百战百胜。我也是站在巨人的肩膀上才能写出这俩篇文章,在此感谢csdn上各位前辈的无私奉献,特别感谢同事大佬的支持和解答。这也算是自己的成长。长路漫漫,砥砺前行!共勉

 

结语

编码可能不咋规范,编码规范这块还需提升,各位将就着看  哈哈。项目工程稍后会上传,可能会有bug还请各位海涵。

 

工程已上传:https://download.csdn.net/download/klaus9/11650921

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
QTextEdit是一个常见的用于输入和编辑文本Qt组件。根据您的问题,我可以简要地解释一下QTextEdit的拖拽功能。 QTextEdit支持两种类型的拖拽操作:拖拽进QTextEdit和从QTextEdit拖拽出去。 首先,让我们来看看拖拽进QTextEdit的情况。如果您想将一些文本或者其他可拖拽的数据拖拽到QTextEdit中,您需要先将数据设置为可拖拽的项。您可以使用QDrag类来实现这个功能。具体来说,您可以在源组件上调用QDrag开始拖拽操作,并设置要拖拽的数据。在QTextEdit中,您可以重写dragEnterEvent()和dropEvent()方法来处理拖拽操作。在dragEnterEvent()中,您可以检查拖拽的数据类型,并决定是否接受这个拖拽操作。在dropEvent()中,您可以将拖拽的数据插入到QTextEdit中。 其次,如果您想从QTextEdit拖拽出数据,您可以使用setDragEnabled()方法来启用此功能。然后您可以选择要拖拽的文本并拖动鼠标来开始拖拽操作。通过重写dragEnterEvent()和dragMoveEvent()方法,您可以确定拖拽操作是否允许,并设置拖拽的数据类型等信息。如果您希望在拖拽操作完成后执行某些操作,您可以重写dropEvent()方法。 总体而言,QTextEdit的拖拽功能提供了一种方便的方法来与其他组件或应用程序之间交换数据。通过了解QDrag和相关的事件处理方法,您可以自由地控制拖拽操作的行为和数据的传输。希望这个回答对您有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值