若該文爲原創文章,未經允許不得轉載
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客導航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/99946795
各位讀者,知識無窮而人力有窮,要麼改需求,要麼找專業人士,要麼自己研究
紅胖子(紅模仿)的博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中...(點擊傳送門)
Qt開發專欄:三方庫開發技術(點擊傳送門)
前話
白板業務需求,需要內部兼容打開pdf。
PDF打開方案
- 方案一:調用外部應用打開pdf
該方案是調用外部exe,另起進程以命令行形式打開。
- 方案二:使用組件打開pdf
使用QAxwidget調用active控件,qt調用active的office控件不穩定性不推薦。
- 方案三:qt應用打開pdf
使用開源庫mupdf調用
- 方案四:使用Pdfium
Pdfium是谷歌開源的祈福閱讀器的部分代碼。
- 方案五:qt應用使用QPdfium打開pdf(本篇使用)
使用QPdfium是封裝了方案四的庫
下載地址
官網git:
git clone –recursive https://github.com/paulovap/qtpdfium
CSDN:https://download.csdn.net/download/qq21497936/11587441
演示Demo
Demo源碼以及運行包下載地址:https://download.csdn.net/download/qq21497936/11587397
編譯qtpdfium
步驟一:移動到文件夾
步驟二:打開工程
步驟三:編譯子工程pdfium
步驟四:出現錯誤”_Printf_format_string_”
編譯出現錯誤,如下圖:
修改源碼如下:
步驟五:漫長的編譯後,出現”error: kernel32.lib”等錯誤
這幾個靜態庫是windows sdk有的,找到windows sdk路徑,沒有的自己裝VS,然後裝windows sdk,筆者是使用mingw編譯,不是msvc
然後將所需要的庫拷貝過去(以提供使用其他編譯器編譯時使用,省麻煩),
修改工程文件
步驟六:繼續漫長的編譯後(十幾分鍾吧),終於編譯成功
Qt模塊使用方法總結
之前寫過qt模塊的融入方法總結,一時找不到於是又總結一下使用的方法:
方法一:將該模塊部署到本地Qt環境當中去
標準使用的方法。
方法二:將該模塊當做第三方庫使用,使用.h和dll庫(筆者推薦)
建議使用該方法,筆者有多臺電腦不適合單獨配置環境,並且從協作開發的角度上來說,他人接手代碼也不應改需要重新配置他自己的開發環境。
方法三:將源碼當做工程源碼直接編譯到工程中
該方法是爲了完全跨平臺,跨編譯器,跨版本,當然會導致編譯時間較長。
方法四:將源碼當做工程lib添加到工程中(優化方案三)
改方法是有方法三的優點,同時又不需要每次編譯,手動編譯一起lib,其他修改工程的時候不再編譯就行。
封裝QtPdfium模塊
關鍵代碼
打開pdf
bool PdfWidget::openFile(QString fileName, QString password)
{
/*
enum Status {
NOT_LOADED = -1,
SUCCESS = 0,
FILE_ERROR = 1,
FORMAT_ERROR = 2,
PASSWORD_ERROR = 3,
HANDLER_ERROR = 4,
FILE_NOT_FOUND_ERROR = 5
};
* */
QPdfium::Status status;
status = _pPdfium->loadFile(fileName, password);
if(status != QPdfium::Status::SUCCESS)
{
qDebug() << "Failed to load file:" << fileName << "error:" << (int)status;
return false;
}
qDebug() << "Succeed to load file:" << fileName << "total pages:" << _pPdfium->pageCount();
_pageCount = _pPdfium->pageCount();
showFirstPage();
return true;
}
是否打開pdf
第一頁
bool PdfWidget::showFirstPage()
{
if(!_pPdfium->isValid())
{
qDebug() << "Failed to" << __FUNCTION__;
return false;
}
if(_pageCount <= 0)
{
qDebug() << "no Page" << __FUNCTION__;
return false;
}
_currentPage = 0;
showPage(_currentPage);
return true;
}
上一頁
bool PdfWidget::showPrevPage()
{
if(!_pPdfium->isValid())
{
qDebug() << "Failed to" << __FUNCTION__;
return false;
}
if(_currentPage > 0)
{
_currentPage--;
showPage(_currentPage);
}
return true;
}
跳轉頁
bool PdfWidget::showPage(int index)
{
if(!_pPdfium->isValid())
{
qDebug() << "Failed to" << __FUNCTION__;
return false;
}
QPdfiumPage page = _pPdfium->page(_currentPage);
float xScale = (float)rect().width() / page.width();
float yScale = (float)rect().height() / page.height();
float minScale = xScale < yScale ? xScale : yScale;
_pixmap = QPixmap::fromImage(page.image(minScale));
update();
}
下一頁
bool PdfWidget::showNextPage()
{
if(!_pPdfium->isValid())
{
qDebug() << "Failed to" << __FUNCTION__;
return false;
}
if(_currentPage < _pageCount - 1)
{
_currentPage++;
showPage(_currentPage);
}
update();
}
最後一頁
bool PdfWidget::showLastPage()
{
if(!_pPdfium->isValid())
{
qDebug() << "Failed to" << __FUNCTION__;
return false;
}
if(_pageCount >= 1)
{
_currentPage = _pageCount - 1;
showPage(_currentPage);
}
update();
}
入坑
入坑一:無法打開中文路徑,“文件錯誤”
解決過程:
步驟一:檢測路徑編碼,各種嘗試,失敗;
步驟二:路徑更換斜槓和反斜槓,失敗
步驟三:路徑前後加引號,失敗
步驟四:調試dll源碼,路徑出打印,到達最核心路徑打開,路徑傳送是正確的;
解決方法:
從源碼上無法解決,但是可以打開中文路徑的時候,先複製到一個非中路的路徑,然後替換中文文件名,從業務上繞開,如programdata目錄。
入坑二:清晰度不夠,修改獲取圖片的比例係數
解決方法:
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客導航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/99946795