头发继续乱 2023-03-19 09:12 采纳率: 47.4%
浏览 77
已结题

滚动条设置不起作用,然后 只能显示第一页pdf

目前问题是 滚动条设置不起作用,然后 只能显示第一页pdf


#include "pdfbrowser.h"
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>

#include <QGraphicsView>

#include <QDebug>
PDFBrowser::PDFBrowser(QWidget *parent)
    : QWidget{parent}
{

    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_StaticContents);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);



    m_scrollArea = new QScrollArea(this);
    vScrollBar = new QScrollBar(Qt::Vertical);
    hScrollBar = new QScrollBar(Qt::Horizontal);
    vScrollBar->setVisible(true);
    hScrollBar->setVisible(true);
    m_scrollArea->setBackgroundRole(QPalette::Base);
    m_scrollArea->setAlignment(Qt::AlignCenter);
    m_scrollArea->setFrameShape(QFrame::Box);
    m_scrollArea->setVerticalScrollBar(vScrollBar);
    m_scrollArea->setHorizontalScrollBar(hScrollBar);
    m_scrollArea->setWidgetResizable(true);
    view = new QGraphicsView();
    scene =  new QGraphicsScene() ;
    m_scrollAreaContentLayout  = new QVBoxLayout;
    scrollAreaContent = new QWidget(this);
    scrollAreaContent->setLayout(m_scrollAreaContentLayout);
    m_scrollArea->setWidget(scrollAreaContent);
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(m_scrollArea);
    label = new QLabel(this);
    m_scrollAreaContentLayout->addWidget(view);
    setLayout(layout);
    connect(vScrollBar, &QScrollBar::valueChanged, this, &PDFBrowser::onScrollBarValueChanged);
    connect(hScrollBar,  &QScrollBar::valueChanged, this, &PDFBrowser::onScrollBarValueChanged);

    document = nullptr;
    qDebug()<<"到这里了";
}

PDFBrowser::~PDFBrowser(){
    if(m_scrollArea!=nullptr)
       delete m_scrollArea;
    if(vScrollBar!=nullptr)
        delete vScrollBar;
    if(hScrollBar!=nullptr)
        delete hScrollBar;

    if(document!=nullptr)
        delete document;

    FPDF_DestroyLibrary();
}


void PDFBrowser::resizeEvent(QResizeEvent *event){


    //在widget重新变更位置时改变scrollba
     QWidget::resizeEvent(event);
     this->m_scrollArea->resize(this->size());
     redraw();

}

PDFDocument* PDFBrowser::loadPDF(const QString& fileName){
    qDebug()<<"hi hi hi555";
    FPDF_InitLibrary();
    FPDF_DOCUMENT pdocument = FPDF_LoadDocument(fileName.toStdString().c_str(), nullptr);

    if (pdocument) {
        PDFDocument* document = new PDFDocument(pdocument);
        document->loadAllPage();
        this->document = document;
        int totalHeight = document->getTotalHeightInPixel();
        int maxWidth = document->getMaxWidthInPixel();
        vScrollBar->setSingleStep(20);
        vScrollBar->setPageStep(20);
        hScrollBar->setSingleStep(20);
        hScrollBar->setPageStep(20);
        vScrollBar->setVisible(true);
        hScrollBar->setVisible(true);
        vScrollBar->setRange(0, totalHeight - m_scrollArea->height());
        hScrollBar->setRange(0, maxWidth - m_scrollArea->width());

        // vScrollBar->setRange(0, 1000);
        // hScrollBar->setRange(0, 1000);
         //vScrollBar->setValue(1);
          qDebug()<<"vScrollBarmaximum loadPDF:"+QString::number(vScrollBar->maximum());
    };
    redraw();
     qDebug()<<"vScrollBarmaximum loadPDF2:"+QString::number(vScrollBar->maximum());
    return  this->document;
}


void PDFBrowser::redraw(){




            if (document == nullptr) {
                return;
            }


           // QPixmap result(m_scrollArea->width(), m_scrollArea->height());

           // QPainter painter(&result);

            // 设置背景颜色
           // painter.setBackground(Qt::darkGray);
           // painter.setBrush(Qt::darkGray);

            // 获取widget大小
            int canvasWidth = m_scrollArea->width();
            int canvasHeight = m_scrollArea->height();

            // 填充矩形区域
            //painter.drawRect(0, 0, canvasWidth, canvasHeight);
           // painter.fillRect(0, 0, canvasWidth, canvasHeight, Qt::white);

            // Get scrollbar position
            int selection = vScrollBar->value();
            int hSelection = hScrollBar->value();
            qDebug()<<"selection:"+QString::number(selection);
            qDebug()<<"hSelection:"+QString::number(hSelection);
            // Get canvas size and calculate beginX
            QSize canvasSize = m_scrollArea->size();
            //居中
            int beginX = 0;
            if (canvasSize.width() > document->getMaxWidthInPixel()) {
                beginX = (canvasSize.width() - document->getMaxWidthInPixel()) / 2;
            }

            // Draw PDF pages to QPixmap and show it on canvas


            QList<QGraphicsPixmapItem*> items;

            int pageAtY = selection;
            PDFPage *page = document->getPageAtPixel(pageAtY);
            //获取当前页是第几页
            int index = page->getIndex();
            //前几页的总长度
            int temp = 0;
            for(int i=0;i<index;i++){
                temp+=document->getAllPage()[i].getPageSizeInPixel(document->getFPdf_DOCUMENT())[1];
            }
          //  painter.setBrush(QColor(Qt::white));
            // 绘制矩形并填充背景色
            int x = -hSelection + beginX;
            int y = 0;
            int width = document->getMaxWidthInPixel();
            int height = canvasHeight;
            //painter.drawRect(x, y, width, height);
            //painter.fillRect(x, y, width, height, painter.brush());

            // 当前页应该在这个位置绘制
            int maginY = temp - selection;
            int paintedCount = 0;
            int drawY = maginY;
            PDFPage *currentPage = nullptr;

            while (paintedCount <=3000) {

                page = document->getPageAtPixel(pageAtY);
                if(page==nullptr)
                    return;
                 qDebug()<<"pageIndex:"+QString::number(page->getIndex());
                if (currentPage == page) {
                    break;
                }
                currentPage = page;
                int pageWidth = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[0];
                int pageHeight = currentPage->getPageSizeInPixel(this->document->getFPdf_DOCUMENT())[1];
                qDebug()<<"paintedCount:"+QString::number(paintedCount);
                qDebug()<<"currentPage:"+ QString::number(currentPage->getIndex());
                 QGraphicsPixmapItem* item = new QGraphicsPixmapItem(currentPage->render(-hSelection + beginX, drawY, pageWidth, pageHeight, 0, 0));
                item->setPos(-hSelection + beginX, drawY+1);
                items.append(item);
                // 已经绘制了这么多,离整个clientArea还有一段距离,不够的话接着取下一页
                paintedCount += pageHeight + maginY;
                // 下一页的坐标(滚动条偏移+当前页大小+偏移),多一个像素去寻找下一页
                pageAtY = pageHeight + selection + maginY + 1;
                // 下一页画的y坐标
                drawY += pageHeight;
            }

          //  int px = -hSelection + beginX;
           // int py = maginY;

            // 在绘图设备上绘制所有QPixmap
           // foreach (const QPixmap& pixmap, list) {
             //   painter.drawPixmap(px, py, pixmap);

               // int x1 = px;
                //int y1 = pixmap.height() + py + 1;
                //int x2 = pixmap.width() + px;
                //int y2 = y1;
                //painter.drawLine(x1, y1, x2, y2);

                //py += pixmap.height() + 1; // 两个QPixmap之间加上10px的间距
            //}
            qDebug()<<"items:"+QString::number(items.size());
            scene->clear();
           int i = 0;
           scene->addItem(items[1]);
            foreach(QGraphicsPixmapItem* item, items) {
                    if(i==2)
                        continue;
                    i++;
                   qDebug()<<"item-x:"+QString::number(item->x())+" item-y"+QString::number(item->y());
                  // scene->addItem(item);
            }
            // 在绘图设备上绘制所有QGraphicsPixmapItem
            qDebug()<<"scene:"+QString::number(scene->sceneRect().height());
            view->setScene(scene);
            //scene.render(&painter);

            //label->setPixmap(result);


        //    painter.end();


}

#ifndef PDFBROWSER_H
#define PDFBROWSER_H
#include<QLabel>
#include<QScrollBar>
#include<QGridLayout>
#include "pdfdocument.h"
#include <QWidget>
#include <QPainter>
#include <QScrollArea>
#include <QString>
#include <QGraphicsView>
class PDFBrowser : public QWidget
{

public:
     PDFBrowser(QWidget *parent);
    ~PDFBrowser();
     PDFDocument* loadPDF(const QString& fileName);

public slots:
     void onScrollBarValueChanged(){
         qDebug()<<"vScrollBarmaximum:"+QString::number(vScrollBar->maximum());
             qDebug()<<"m_scrollArea:"+QString::number(m_scrollArea->height());
      qDebug()<<"scrollAreaContent:"+QString::number(scrollAreaContent->height());
          qDebug()<<"vScrollBarvalue:"+QString::number(vScrollBar->value());
         this->redraw();
     }
protected:
     void resizeEvent(QResizeEvent *event) override ;

private:
         QScrollBar* vScrollBar = nullptr;
         QScrollBar* hScrollBar = nullptr;
         QScrollArea* m_scrollArea = nullptr;
          QVBoxLayout* m_scrollAreaContentLayout;
         PDFDocument* document;
         QWidget *scrollAreaContent;
          QLabel  *label;
          QGraphicsView* view;
          QGraphicsScene* scene;
         void redraw();



};

#endif // PDFBROWSER_H
#include "pdfpage.h"
#include "fpdfview.h"
#include <QApplication>
#include <QScreen>
PDFPage::PDFPage(int index) {


    this->index = index;
}
int PDFPage::toPixel(int size) {
    int dpi = QGuiApplication::primaryScreen()->physicalDotsPerInch();

    return size * dpi / 72;
}

QList<int> PDFPage::getPageSize(const FPDF_DOCUMENT& document) {
    if (this->wh.size() > 1)
        return this->wh;

    // 计算需要的图像大小(以像素为单位)
      // int width = FPDF_GetPageWidth(page) * dpi / 72.0;
       //int height = FPDF_GetPageHeight(page) * dpi / 72.0;

    double pageWidth = 0.0;
    double pageHeight = 0.0;

    if (FPDF_GetPageSizeByIndex(document, index, &pageWidth, &pageHeight)) {
        this->wh.append((int)pageWidth);
        this->wh.append((int)pageHeight);
    }
    return this->wh;
}


QPixmap PDFPage::render(
    int start_x,
    int start_y,
    int size_x,
    int size_y,
    int rotate,
    int flags) {

     FPDF_BITMAP bitmap  = FPDFBitmap_Create(size_x, size_y, 1);

     double x  = 0;
     double y = 0;

     x = FPDF_GetPageWidthF(page);
     y = FPDF_GetPageHeightF(page);
     qDebug()<<"x:"+QString::number(x)+" y:"+QString::number(y)+" size_x:"+QString::number(size_x)+" size_y:"+QString::number(size_y);

     FPDFBitmap_FillRect(bitmap, start_x, start_y, size_x, size_y, 0xFFFFFFFF);
     FPDF_RenderPageBitmap(bitmap, page, start_x, start_y, size_x, size_y, 0, FPDF_ANNOT);
     // 获取位图数据缓冲区的指针和行距信息
     unsigned char* buffer = (unsigned char*)FPDFBitmap_GetBuffer(bitmap);
     int stride = FPDFBitmap_GetStride(bitmap);
     // 创建QImage对象
     QImage image(buffer, size_x, size_y, stride, QImage::Format_ARGB32);
     // 将QImage对象转换为QPixmap对象
     QPixmap pixmap = QPixmap::fromImage(image);
     FPDFBitmap_Destroy(bitmap);
     return pixmap;
}

int PDFPage::getIndex() {
    return this->index;
}

QList<int> PDFPage::getPageSizeInPixel(const FPDF_DOCUMENT& document) {
    QList<int> pageSize = getPageSize(document);
    QList<int> NewOne;
    NewOne.append(toPixel(pageSize[0]));
    NewOne.append(toPixel(pageSize[1]));
    return NewOne;
}

float PDFPage::getWHRatio(const FPDF_DOCUMENT& document) {
    QList<int> pageSize = getPageSize(document);
    return (float)(pageSize[1] / pageSize[0]);
}

void PDFPage::close() const {
    FPDF_ClosePage(this->page);
}




  • 写回答

3条回答 默认 最新

  • 追cium 2023-03-19 09:16
    关注

    参考GPT和自己的思路:

    根据代码,可以看出可能存在以下问题:

    1. 滚动条设置不起作用

    可能的原因是没有正确设置滚动条参数,可以检查一下代码中vScrollBarhScrollBarsingleSteppageSteprange是否正确。

    1. 只能显示第一页PDF

    可能的原因是在绘制PDF页面时只绘制了一页,可以检查一下代码中的绘制PDF页面的函数redraw(),并查看在循环中是否正确绘制了所有的页面。

    另外还需要检查一些细节问题,比如:

    1. 在加载PDF文件前是否调用了FPDF_InitLibrary()函数?
    2. 是否正确释放了资源,比如关闭了页面FPDF_ClosePage()并销毁了文档FPDF_CloseDocument()

    建议在调试过程中加入调试语句,以便更好地定位问题的所在。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月25日
  • 已采纳回答 1月17日
  • 创建了问题 3月19日

悬赏问题

  • ¥15 vue请求不到数据,返回状态200,数据为html
  • ¥15 访问url时不会自动调用其 Servlet的doGet()
  • ¥15 用白鹭引擎开发棋牌游戏的前端为什么这么难找
  • ¥15 MATLAB解决问题
  • ¥35 哪位专业人士知道这是什么原件吗?哪里可以买到?
  • ¥15 关于#c##的问题:treenode反序列化后获取不到上一节点和下一节点,Fullpath和Handle报错
  • ¥15 一部手机能否同时用不同的app进入不同的直播间?
  • ¥20 输入import torch显示Intel MKL FATAL ERROR,系统驱动1%,: Cannot load mkl_intel_thread.dll.
  • ¥15 点云密度大则包围盒小
  • ¥15 nginx使用nfs进行服务器的数据共享