Qt三方庫開發技術:Qt應用內部打開PDF文件

若該文爲原創文章,未經允許不得轉載
原博主博客地址: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章