QString::toWCharArray方法说明

本文介绍在mingw32与QT5.2.1环境下,如何使用QString::toWCharArray方法将QString转换为wchar_t数组,并强调了转换后的数组需手动添加结束符''的重要性。未添加结束符可能导致后续操作如转换为char*时出现奇怪字符。

环境:mingw32、QT5.2.1

QString::toWCharArray方法用于将QString类型转换成wchar_t类型的数组,但是转换后数组末尾不会加上结束符 '\0',如果不加处理,在做其他操作时,例如将QString转换成char*后,转换的结果末尾会多出一些奇怪的字符。所以需要我们手动加上结束符 '\0'。

QString str = "ceshi";
wchar_t *pWideChar = new wchar_t[str.size()+1];
int actualLen = str.toWCharArray(pWideChar);
// 加结束符'\0'
pWideChar[actualLen] = '\0';
// 转换char*操作
...
...
...

 

#include "pptcominterface.h" #include <QDebug> #include <QFileInfo> #include <QDir> #ifdef _WIN32 #include <comdef.h> #include <atlbase.h> #include <atlcom.h> #endif QStringList PptComInterface::getPptContent(const QString &filePath) { QStringList contentList; #ifdef _WIN32 // Windows环境下使用COM接口获取PPT内容 CoInitialize(NULL); try { // 创建WPS演示文稿应用对象 CLSID clsid; HRESULT hr = CLSIDFromProgID(L"kso.Application", &clsid); if (FAILED(hr)) { qDebug() << "Failed to get CLSID for kso.Application"; CoUninitialize(); return contentList; } IDispatch *pApp = NULL; hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pApp); if (FAILED(hr)) { qDebug() << "Failed to create WPS Application instance"; CoUninitialize(); return contentList; } // 设置应用可见性 VARIANT x; x.vt = VT_I4; x.lVal = 0; // 不可见 const OLECHAR *szVisible = L"Visible"; DISPID dispidVisible; hr = pApp->GetIDsOfNames(IID_NULL, &szVisible, 1, LOCALE_USER_DEFAULT, &dispidVisible); if (SUCCEEDED(hr)) { DISPPARAMS params = { &x, NULL, 1, 0 }; pApp->Invoke(dispidVisible, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL); } // 打开演示文稿 const OLECHAR *szPresentations = L"Presentations"; DISPID dispidPresentations; hr = pApp->GetIDsOfNames(IID_NULL, &szPresentations, 1, LOCALE_USER_DEFAULT, &dispidPresentations); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return contentList; } VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = pApp->Invoke(dispidPresentations, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return contentList; } IDispatch *pPresentations = result.pdispVal; // 准备文件路径 QString qFilePath = QDir::toNativeSeparators(filePath); wchar_t wFilePath[MAX_PATH]; qFilePath.toWCharArray(wFilePath); wFilePath[qFilePath.length()] = 0; // 创建参数 VARIANTARG args[1]; args[0].vt = VT_BSTR; args[0].bstrVal = SysAllocString(wFilePath); const OLECHAR *szOpen = L"Open"; DISPID dispidOpen; hr = pPresentations->GetIDsOfNames(IID_NULL, &szOpen, 1, LOCALE_USER_DEFAULT, &dispidOpen); if (FAILED(hr)) { VariantClear(&args[0]); pPresentations->Release(); pApp->Release(); CoUninitialize(); return contentList; } DISPPARAMS paramsOpen = { args, NULL, 1, 0 }; hr = pPresentations->Invoke(dispidOpen, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsOpen, &result, NULL, NULL); VariantClear(&args[0]); if (FAILED(hr)) { pPresentations->Release(); pApp->Release(); CoUninitialize(); return contentList; } IDispatch *pPresentation = result.pdispVal; // 提取PPT内容 contentList = extractTextFromPresentation(pPresentation); // 清理 pPresentation->Release(); pPresentations->Release(); pApp->Release(); } catch (...) { qDebug() << "Exception occurred while accessing PPT via COM"; } CoUninitialize(); #else // Linux环境下返回空列表,使用模拟内容 Q_UNUSED(filePath); #endif return contentList; } #ifdef _WIN32 QStringList PptComInterface::extractTextFromPresentation(IDispatch *presentation) { QStringList contentList; try { // 获取Slides集合 const OLECHAR *szSlides = L"Slides"; DISPID dispidSlides; HRESULT hr = presentation->GetIDsOfNames(IID_NULL, &szSlides, 1, LOCALE_USER_DEFAULT, &dispidSlides); if (FAILED(hr)) return contentList; VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = presentation->Invoke(dispidSlides, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) return contentList; IDispatch *pSlides = result.pdispVal; // 获取Slides数量 const OLECHAR *szCount = L"Count"; DISPID dispidCount; hr = pSlides->GetIDsOfNames(IID_NULL, &szCount, 1, LOCALE_USER_DEFAULT, &dispidCount); if (FAILED(hr)) { pSlides->Release(); return contentList; } VariantInit(&result); hr = pSlides->Invoke(dispidCount, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pSlides->Release(); return contentList; } int slideCount = result.intVal; // 遍历每个Slide for (int i = 1; i <= slideCount; i++) { VARIANTARG args[1]; args[0].vt = VT_I4; args[0].lVal = i; const OLECHAR *szItem = L"Item"; DISPID dispidItem; hr = pSlides->GetIDsOfNames(IID_NULL, &szItem, 1, LOCALE_USER_DEFAULT, &dispidItem); if (FAILED(hr)) continue; DISPPARAMS paramsItem = { args, NULL, 1, 0 }; VariantInit(&result); hr = pSlides->Invoke(dispidItem, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsItem, &result, NULL, NULL); if (FAILED(hr)) continue; IDispatch *pSlide = result.pdispVal; // 提取Slide内容 QString slideContent = extractTextFromSlide(pSlide); if (!slideContent.isEmpty()) { contentList << slideContent; } pSlide->Release(); } pSlides->Release(); } catch (...) { qDebug() << "Exception occurred while extracting PPT content"; } return contentList; } QString PptComInterface::extractTextFromSlide(IDispatch *slide) { QString slideContent; try { // 获取Shapes集合 const OLECHAR *szShapes = L"Shapes"; DISPID dispidShapes; HRESULT hr = slide->GetIDsOfNames(IID_NULL, &szShapes, 1, LOCALE_USER_DEFAULT, &dispidShapes); if (FAILED(hr)) return slideContent; VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = slide->Invoke(dispidShapes, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) return slideContent; IDispatch *pShapes = result.pdispVal; // 获取Shapes数量 const OLECHAR *szCount = L"Count"; DISPID dispidCount; hr = pShapes->GetIDsOfNames(IID_NULL, &szCount, 1, LOCALE_USER_DEFAULT, &dispidCount); if (FAILED(hr)) { pShapes->Release(); return slideContent; } VariantInit(&result); hr = pShapes->Invoke(dispidCount, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pShapes->Release(); return slideContent; } int shapeCount = result.intVal; // 遍历每个Shape for (int i = 1; i <= shapeCount; i++) { VARIANTARG args[1]; args[0].vt = VT_I4; args[0].lVal = i; const OLECHAR *szItem = L"Item"; DISPID dispidItem; hr = pShapes->GetIDsOfNames(IID_NULL, &szItem, 1, LOCALE_USER_DEFAULT, &dispidItem); if (FAILED(hr)) continue; DISPPARAMS paramsItem = { args, NULL, 1, 0 }; VariantInit(&result); hr = pShapes->Invoke(dispidItem, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsItem, &result, NULL, NULL); if (FAILED(hr)) continue; IDispatch *pShape = result.pdispVal; // 提取Shape内容 QString shapeText = extractTextFromShape(pShape); if (!shapeText.isEmpty()) { if (!slideContent.isEmpty()) slideContent += "<br>"; slideContent += shapeText; } pShape->Release(); } pShapes->Release(); } catch (...) { qDebug() << "Exception occurred while extracting slide content"; } return slideContent; } QString PptComInterface::extractTextFromShape(IDispatch *shape) { QString shapeText; try { // 获取TextFrame const OLECHAR *szTextFrame = L"TextFrame"; DISPID dispidTextFrame; HRESULT hr = shape->GetIDsOfNames(IID_NULL, &szTextFrame, 1, LOCALE_USER_DEFAULT, &dispidTextFrame); if (FAILED(hr)) return shapeText; VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = shape->Invoke(dispidTextFrame, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) return shapeText; if (result.vt == VT_DISPATCH && result.pdispVal != NULL) { IDispatch *pTextFrame = result.pdispVal; // 获取TextRange const OLECHAR *szTextRange = L"TextRange"; DISPID dispidTextRange; hr = pTextFrame->GetIDsOfNames(IID_NULL, &szTextRange, 1, LOCALE_USER_DEFAULT, &dispidTextRange); if (SUCCEEDED(hr)) { VariantInit(&result); hr = pTextFrame->Invoke(dispidTextRange, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (SUCCEEDED(hr) && result.vt == VT_DISPATCH && result.pdispVal != NULL) { IDispatch *pTextRange = result.pdispVal; // 获取Text const OLECHAR *szText = L"Text"; DISPID dispidText; hr = pTextRange->GetIDsOfNames(IID_NULL, &szText, 1, LOCALE_USER_DEFAULT, &dispidText); if (SUCCEEDED(hr)) { VariantInit(&result); hr = pTextRange->Invoke(dispidText, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (SUCCEEDED(hr) && result.vt == VT_BSTR) { shapeText = QString::fromWCharArray(result.bstrVal); } } pTextRange->Release(); } } pTextFrame->Release(); } } catch (...) { qDebug() << "Exception occurred while extracting shape text"; } return shapeText; } #endif bool PptComInterface::openPptInWps(const QString &filePath) { #ifdef _WIN32 // 使用ShellExecute打开PPT文件 QString qFilePath = QDir::toNativeSeparators(filePath); wchar_t wFilePath[MAX_PATH]; qFilePath.toWCharArray(wFilePath); wFilePath[qFilePath.length()] = 0; HINSTANCE result = ShellExecute(NULL, L"open", wFilePath, NULL, NULL, SW_SHOWNORMAL); return (INT_PTR)result > 32; #else Q_UNUSED(filePath); return false; #endif } bool PptComInterface::startSlideShow(const QString &filePath) { #ifdef _WIN32 CoInitialize(NULL); try { // 创建WPS演示文稿应用对象 CLSID clsid; HRESULT hr = CLSIDFromProgID(L"kso.Application", &clsid); if (FAILED(hr)) { CoUninitialize(); return false; } IDispatch *pApp = NULL; hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pApp); if (FAILED(hr)) { CoUninitialize(); return false; } // 设置应用可见 VARIANT x; x.vt = VT_I4; x.lVal = 1; // 可见 const OLECHAR *szVisible = L"Visible"; DISPID dispidVisible; hr = pApp->GetIDsOfNames(IID_NULL, &szVisible, 1, LOCALE_USER_DEFAULT, &dispidVisible); if (SUCCEEDED(hr)) { DISPPARAMS params = { &x, NULL, 1, 0 }; pApp->Invoke(dispidVisible, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL); } // 打开演示文稿 const OLECHAR *szPresentations = L"Presentations"; DISPID dispidPresentations; hr = pApp->GetIDsOfNames(IID_NULL, &szPresentations, 1, LOCALE_USER_DEFAULT, &dispidPresentations); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return false; } VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = pApp->Invoke(dispidPresentations, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶msNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return false; } IDispatch *pPresentations = result.pdispVal; // 准备文件路径 QString qFilePath = QDir::toNativeSeparators(filePath); wchar_t wFilePath[MAX_PATH]; qFilePath.toWCharArray(wFilePath); wFilePath[qFilePath.length()] = 0; // 打开文件 VARIANTARG args[1]; args[0].vt = VT_BSTR; args[0].bstrVal = SysAllocString(wFilePath); const OLECHAR *szOpen = L"Open"; DISPID dispidOpen; hr = pPresentations->GetIDsOfNames(IID_NULL, &szOpen, 1, LOCALE_USER_DEFAULT, &dispidOpen); if (FAILED(hr)) { VariantClear(&args[0]); pPresentations->Release(); pApp->Release(); CoUninitialize(); return false; } DISPPARAMS paramsOpen = { args, NULL, 1, 0 }; hr = pPresentations->Invoke(dispidOpen, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsOpen, &result, NULL, NULL); VariantClear(&args[0]); if (FAILED(hr)) { pPresentations->Release(); pApp->Release(); CoUninitialize(); return false; } IDispatch *pPresentation = result.pdispVal; // 开始幻灯片放映 const OLECHAR *szSlideShowSettings = L"SlideShowSettings"; DISPID dispidSlideShowSettings; hr = pPresentation->GetIDsOfNames(IID_NULL, &szSlideShowSettings, 1, LOCALE_USER_DEFAULT, &dispidSlideShowSettings); if (SUCCEEDED(hr)) { VariantInit(&result); hr = pPresentation->Invoke(dispidSlideShowSettings, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (SUCCEEDED(hr) && result.vt == VT_DISPATCH && result.pdispVal != NULL) { IDispatch *pSlideShowSettings = result.pdispVal; const OLECHAR *szRun = L"Run"; DISPID dispidRun; hr = pSlideShowSettings->GetIDsOfNames(IID_NULL, &szRun, 1, LOCALE_USER_DEFAULT, &dispidRun); if (SUCCEEDED(hr)) { DISPPARAMS paramsRun = { NULL, NULL, 0, 0 }; pSlideShowSettings->Invoke(dispidRun, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsRun, NULL, NULL, NULL); } pSlideShowSettings->Release(); } } pPresentation->Release(); pPresentations->Release(); pApp->Release(); } catch (...) { qDebug() << "Exception occurred while starting slide show"; } CoUninitialize(); return true; #else Q_UNUSED(filePath); return false; #endif } 请检查编译错误D:\qt\wps\PPT6\ppt12\pptcominterface.cpp:45: error: C2664: “HRESULT IDispatch::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *)”: 无法将参数 2 从“const OLECHAR **”转换为“LPOLESTR *”
11-09
Qt 中将数据序列化为 JSON 对象时,如果出现中文乱码问题,通常是由于编码问题导致的。为了确保 JSON 文件中的中文字符能够正确显示,可以采取以下方法来解决: 1. **确保字符串编码正确**: - 在将 `std::string` 转换为 `QString` 时,确保 `std::string` 的编码是 UTF-8。如果不是,需要进行编码转换。 - 使用 `QString::fromUtf8()` 代替 `QString::fromStdString()`,以确保字符串以 UTF-8 编码进行转换。 2. **设置 JSON 输出的编码**: - 使用 `QJsonDocument` 将 `QJsonObject` 转换为 JSON 字符串时,确保输出的编码是 UTF-8。 以下是修改后的代码示例: ```cpp QJsonObject AppConfig::toJson() const { QJsonObject json; json["PluginPath"] = QString::fromUtf8(PluginPath.c_str()); // 使用 fromUtf8 json["Version"] = QString::fromUtf8(Version.c_str()); json["JsonOutputRelativePath"] = QString::fromUtf8(JsonOutputRelativePath.c_str()); json["DxfOutputRelativePath"] = QString::fromUtf8(DxfOutputRelativePath.c_str()); json["DxfThumbRelativePath"] = QString::fromUtf8(DxfThumbRelativePath.c_str()); json["FileNameSuffix"] = QString::fromUtf8(FileNameSuffix.c_str()); json["AppPath"] = QString::fromUtf8(AppPath.c_str()); json["DxfTransToolPath"] = QString::fromUtf8(DxfTransToolPath.c_str()); json["DxfTransToolName"] = QString::fromUtf8(DxfTransToolName.c_str()); json["PermeateToolName"] = QString::fromUtf8(PermeateToolName.c_str()); json["PermeateToolPath"] = QString::fromUtf8(PermeateToolPath.c_str()); json["PermeateOutputPath"] = QString::fromUtf8(PermeateOutputPath.c_str()); json["StableToolPath"] = QString::fromUtf8(StableToolPath.c_str()); json["StableToolName"] = QString::fromUtf8(StableToolName.c_str()); json["StableOutputPath"] = QString::fromUtf8(StableOutputPath.c_str()); return json; } // 在需要输出 JSON 文件的地方 void saveJsonToFile(const QJsonObject &json, const QString &filePath) { QJsonDocument doc(json); QByteArray jsonData = doc.toJson(QJsonDocument::Indented); // 确保输出为 UTF-8 QFile file(filePath); if (file.open(QIODevice::WriteOnly)) { file.write(jsonData); file.close(); } } ``` ### 关键点说明: - 使用 `QString::fromUtf8()` 代替 `QString::fromStdString()`,确保 `std::string` 以 UTF-8 编码正确转换为 `QString`。 - 使用 `QJsonDocument::toJson()` 生成 JSON 数据时,默认输出为 UTF-8 编码,无需额外设置。 ### 其他可能的解决方案: - 如果 `std::string` 的编码不是 UTF-8,可以先将其转换为 UTF-8 编码的 `QByteArray`,然后再转换为 `QString`。 - 确保你的源代码文件本身是以 UTF-8 编码保存的,避免在编译过程中引入编码问题。 通过以上方法,可以有效地解决 JSON 文件中中文乱码的问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值